package cn.gson.financial.kernel.service.impl;

import cn.gson.financial.kernel.common.DateUtil;
import cn.gson.financial.kernel.common.DoubleComparer;
import cn.gson.financial.kernel.common.DoubleValueUtil;
import cn.gson.financial.kernel.excelexport.AllAccountExport;
import cn.gson.financial.kernel.constans.ComprehensiveParamesConstans;
import cn.gson.financial.kernel.dao.ComprehensiveParamsDao;
import cn.gson.financial.kernel.exception.ServiceException;
import cn.gson.financial.kernel.model.entity.*;
import cn.gson.financial.kernel.model.entity.Currency;
import cn.gson.financial.kernel.model.mapper.*;
import cn.gson.financial.kernel.model.vo.*;
import cn.gson.financial.kernel.service.ReportTemplateService;
import cn.gson.financial.kernel.service.SubjectService;
import cn.gson.financial.kernel.service.VoucherService;
import cn.gson.financial.kernel.utils.BaseUtil;
import cn.gson.financial.kernel.utils.TimeUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@AllArgsConstructor
public class VoucherServiceImpl extends ServiceImpl<VoucherMapper, Voucher> implements VoucherService {

    private VoucherDetailsMapper detailsMapper;

    private SubjectMapper subjectMapper;

    private VoucherDetailsAuxiliaryMapper voucherDetailsAuxiliaryMapper;

    private SubjectService subjectService;

    private CheckoutMapper checkoutMapper;

    private AccountSetsMapper accountSetsMapper;

    private ReportTemplateService reportTemplateService;

    private AllSelectMapper allSelectMapper;

    @Override
    public int batchInsert(List<Voucher> list) {
        return baseMapper.batchInsert(list);
    }

    @Override
    public List<Voucher> list(Wrapper<Voucher> queryWrapper) {
        return baseMapper.selectVoucher(queryWrapper);
    }

    @Override
    public IPage<Voucher> page(IPage<Voucher> page, Wrapper<Voucher> queryWrapper) {
        return baseMapper.selectVoucher(page, queryWrapper);
    }

    @Override
    public int loadCode(Integer accountSetsId, String word, Date currentAccountDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentAccountDate);
        Integer code = baseMapper.selectMaxCode(accountSetsId, word, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONDAY) + 1);
        return code == null ? 1 : code;
    }

    @Override
    public List accountBookDetails(Integer accountSetsId, Integer subjectId, Date accountDate, String subjectCode, Boolean showNumPrice) {
        return this.summary(accountSetsId, subjectId, accountDate, subjectCode, showNumPrice, true);
    }

    @Override
    public List supAccountBookDetails(AccountBookVo vo,Integer accountSetsId, Integer subjectId, List<String> date, String subjectCode, Boolean showNumPrice,Integer currencyId) {
        System.out.println(currencyId);
        if(currencyId== -1||currencyId==-2){
            return this.summaryAccountBook(vo,accountSetsId, subjectId, date, subjectCode, true, currencyId);
        }else {
            return this.summaryCurrency(vo,accountSetsId, subjectId, date, subjectCode, true, currencyId);
        }

    }

    @Override
    public List accountGeneralLedger(Integer accountSetsId, Date accountDate, Boolean showNumPrice) {
        List<Subject> subjectList = subjectService.accountBookList(accountDate, accountSetsId, showNumPrice);
        List<Map<String, Object>> data = new ArrayList<>(subjectList.size());
        subjectList.forEach(subject -> {
            List<VoucherDetailVo> summary = this.summary(accountSetsId, subject.getId(), accountDate, subject.getCode(), showNumPrice, false);
            Map<String, Object> item = new HashMap<>(2);
            item.put("subject", subject);
            item.put("summary", summary);
            data.add(item);
        });
        return data;
    }

    private List<VoucherDetailVo> setSummary(VoucherDetailVo voucherDetailVo,VoucherDetailVo accumulatedThisYearVo,String startTime){
        List<VoucherDetailVo> summaryList = new ArrayList<>();
        voucherDetailVo.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime));
        //期初余额set进去
        summaryList.add(voucherDetailVo);
        //本期合计set进去
        VoucherDetailVo summary = new VoucherDetailVo();

        Double balance = (voucherDetailVo.getBalance() == null ?0:voucherDetailVo.getBalance());
        Double currencyBalance = (voucherDetailVo.getCurrencyBalance() == null ?0:voucherDetailVo.getCurrencyBalance());
        if (balance<0 && currencyBalance<=0){
            summary.setBalance(-voucherDetailVo.getBalance());
            summary.setCurrencyBalance(-voucherDetailVo.getCurrencyBalance());
            if (voucherDetailVo.getBalanceDirection().equals("借")){
                summary.setBalanceDirection("贷");
            }else {
                summary.setBalanceDirection("借");
            }
        }else {
            summary.setBalance(voucherDetailVo.getBalance());
            summary.setCurrencyBalance(voucherDetailVo.getCurrencyBalance());
            summary.setBalanceDirection(voucherDetailVo.getBalanceDirection());
        }

        summary.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime));
        summary.setSummary("本期合计");
        summaryList.add(summary);
        //本年累计set进去
        summaryList.add(accumulatedThisYearVo);
        return summaryList;
    }

    /**
    * @Description:
    * @Param: [initialBalanceVo 期初 summary.get(0)
     * , accountThisYearVo, 本年累计
     * accSetsId, subjectId, startTime, enableDate]
    * @return: cn.gson.financial.kernel.model.vo.VoucherDetailVo
    */
    private VoucherDetailVo selectAccountThisYear(VoucherDetailVo initialBalanceVo, VoucherDetailVo accountThisYearVo,Integer accSetsId,Integer subjectId,String startTime,Date enableDate){

        if(accountThisYearVo == null){
            accountThisYearVo = new VoucherDetailVo();
            //说明本年没有用该科目做过帐
            accountThisYearVo.setSummary("本年累计");
            System.out.println("cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,\"yyyy-MM-dd\")===" + cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd"));
            if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd")) == cn.gson.financial.kernel.utils.DateUtil.getYear(enableDate)){
                //查询该科目设置的期初
                VoucherDetailVo startDetail = baseMapper.findStartDetail(accSetsId,subjectId);
                if (startDetail!=null){
                    System.out.println("Llllll===" + startDetail);
                    accountThisYearVo.setCreditAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeCredit()));
                    accountThisYearVo.setDebitAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeDebit()));
                    accountThisYearVo.setCurrencyDebit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeDebit()));
                    accountThisYearVo.setCurrencyCredit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeCredit()));
                }
            }


            Double balance = (initialBalanceVo.getBalance() == null ?0:initialBalanceVo.getBalance());
            Double currencyBalance = (initialBalanceVo.getCurrencyBalance() == null ?0:initialBalanceVo.getCurrencyBalance());
            if (balance < 0 && currencyBalance <= 0){
                accountThisYearVo.setBalance(-initialBalanceVo.getBalance());
                accountThisYearVo.setCurrencyBalance(-initialBalanceVo.getCurrencyBalance());
                if (initialBalanceVo.getBalanceDirection().equals("借")){
                    accountThisYearVo.setBalanceDirection("贷");
                }else if(initialBalanceVo.getBalanceDirection().equals("平")) {
                    accountThisYearVo.setBalanceDirection("平");
                }else {
                    accountThisYearVo.setBalanceDirection("借");
                }
            }else {
                accountThisYearVo.setBalance(initialBalanceVo.getBalance());
                accountThisYearVo.setCurrencyBalance(initialBalanceVo.getCurrencyBalance());
                accountThisYearVo.setBalanceDirection(initialBalanceVo.getBalanceDirection());
            }
        }else {
            System.out.println("cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,\"yyyy-MM-dd\")===" + cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd"));
            if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd")) == cn.gson.financial.kernel.utils.DateUtil.getYear(enableDate)){
                //查询该科目设置的期初
                VoucherDetailVo startDetail = baseMapper.findStartDetail(accSetsId,subjectId);
                if (startDetail!=null){
                    accountThisYearVo.setCreditAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeCredit())+BaseUtil.checkDoubleIsNull(accountThisYearVo.getCreditAmount()));
                    accountThisYearVo.setDebitAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeDebit())+ BaseUtil.checkDoubleIsNull(accountThisYearVo.getDebitAmount()));
                    accountThisYearVo.setCurrencyDebit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeDebit()) + BaseUtil.checkDoubleIsNull(accountThisYearVo.getCurrencyDebit()));
                    accountThisYearVo.setCurrencyCredit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeCredit()) + BaseUtil.checkDoubleIsNull(accountThisYearVo.getCurrencyCredit()));
                }
            }
            double he = DoubleValueUtil.getNotNullVal(accountThisYearVo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(accountThisYearVo.getCreditAmount());
            VoucherDetailVo init = initialBalanceVo;//将期初数据赋值给init
            double currencySum = DoubleValueUtil.getNotNullVal(accountThisYearVo.getCurrencyDebit()) - DoubleValueUtil.getNotNullVal(accountThisYearVo.getCurrencyCredit());
            switch (accountThisYearVo.getBalanceDirection()) {

                case "借":
                    Double balanceSum1  = DoubleValueUtil.getNotNullVal(init.getBalance()) + he;
                    Double currencyBalanceSum1 = DoubleValueUtil.getNotNullVal(init.getCurrencyBalance()) + currencySum;
                    if (balanceSum1 < 0 && currencyBalanceSum1 <= 0){
                        accountThisYearVo.setBalance(-balanceSum1);
                        accountThisYearVo.setCurrencyBalance(-currencyBalanceSum1);
                        accountThisYearVo.setBalanceDirection("贷");
                    }else {
                        accountThisYearVo.setBalance(balanceSum1);
                        accountThisYearVo.setCurrencyBalance(currencyBalanceSum1);
                    }
                    break;
                case "贷":
                    Double balanceSum2  = DoubleValueUtil.getNotNullVal(init.getBalance()) - he;
                    Double currencyBalanceSum2 = DoubleValueUtil.getNotNullVal(init.getCurrencyBalance()) - currencySum;
                    if (balanceSum2 < 0 && currencyBalanceSum2 <= 0){
                        accountThisYearVo.setBalance(-balanceSum2);
                        accountThisYearVo.setCurrencyBalance(-currencyBalanceSum2);
                        accountThisYearVo.setBalanceDirection("借");
                    }else {
                        accountThisYearVo.setBalance(balanceSum2);
                        accountThisYearVo.setCurrencyBalance(currencyBalanceSum2);
                    }
                    break;
            }
            accountThisYearVo.setNumBalance(accountThisYearVo.getNum());
        }

        return accountThisYearVo;
    }

    @Override
    public List<Map<String, Object>> accountGeneralLedgerByParam(AccountSets accountSets, String startTime, String endTime, String startSubject,
                                                                 String endSubject, Integer startLevel, Integer endLevel,boolean isOpen,
                                                                 boolean showNumPrice,Integer currencyId,List<Subject> subjectList) {
        Integer accSetsId = accountSets.getId();
        List<Map<String, Object>> data = new ArrayList<>(subjectList.size());

        for (Subject subject : subjectList) {
            List<VoucherDetailVo> summary = null;
            try {
                summary = this.summary1(accSetsId, subject.getId(), subject.getCode(), startTime,endTime, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Map<String, Object> item = new HashMap<>(2);
            item.put("subject", this.copySubject(subject));
            if(summary.size() == 1){
                //说明这个月没有做账，只有一个期初，需要将剩下的本期累计和本年累计补上
                //查询本年累计
                VoucherDetailVo vo = baseMapper.accumulatedThisYear(accSetsId,subject.getId(),endTime);
                VoucherDetailVo accountThisYearVo = this.selectAccountThisYear(summary.get(0), vo,accSetsId,subject.getId(),startTime,accountSets.getEnableDate());
                accountThisYearVo.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime));

                List<VoucherDetailVo> detailVos = this.setSummary(summary.get(0), accountThisYearVo, startTime);
                item.put("summary", detailVos);
            }else if (summary.size() == 2){
                //如果是2 的话  就只有期初和本年累计 这时需要将本期累计加入
                VoucherDetailVo vo = null;
                for (VoucherDetailVo voucherDetailVo : summary) {
                    System.out.println(voucherDetailVo);
                    if (voucherDetailVo.getSummary().equals("期初余额")){
                        //把期初数据复制到本期余额里
                        System.out.println("asdscsd ==" + voucherDetailVo);
                        vo = this.copyVoucherDetailVo1(voucherDetailVo);
                    }
                }
                summary.add(1,vo);
                summary.forEach(voucherDetailVo -> {
                    System.out.println(voucherDetailVo);
                    //如果是本年累计的话  需要加上设置的期初
                    if (voucherDetailVo.getSummary().equals("本年累计")){
                        if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd")) == cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())){
                            //查询该科目设置的期初
                            VoucherDetailVo startDetail = baseMapper.findStartDetail(accSetsId,subject.getId());
                            if (startDetail!=null){
                                voucherDetailVo.setCreditAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeCredit())+BaseUtil.checkDoubleIsNull(voucherDetailVo.getCreditAmount()));
                                voucherDetailVo.setDebitAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeDebit())+ BaseUtil.checkDoubleIsNull(voucherDetailVo.getDebitAmount()));
                                voucherDetailVo.setCurrencyDebit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeDebit()) + BaseUtil.checkDoubleIsNull(voucherDetailVo.getCurrencyDebit()));
                                voucherDetailVo.setCurrencyCredit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeCredit()) + BaseUtil.checkDoubleIsNull(voucherDetailVo.getCurrencyCredit()));

                            }
                        }
                    }
                });
                item.put("summary", summary);
            } else {
                summary.forEach(voucherDetailVo -> {
                    System.out.println(voucherDetailVo);
                    //如果是本年累计的话  需要加上设置的期初
                    if (voucherDetailVo.getSummary().equals("本年累计")){
                        if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(startTime,"yyyy-MM-dd")) == cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())){
                            //查询该科目设置的期初
                            VoucherDetailVo startDetail = baseMapper.findStartDetail(accSetsId,subject.getId());
                            if (startDetail!=null){
                                voucherDetailVo.setCreditAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeCredit())+BaseUtil.checkDoubleIsNull(voucherDetailVo.getCreditAmount()));
                                voucherDetailVo.setDebitAmount(BaseUtil.checkDoubleIsNull(startDetail.getCumulativeDebit())+ BaseUtil.checkDoubleIsNull(voucherDetailVo.getDebitAmount()));
                                voucherDetailVo.setCurrencyDebit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeDebit()) + BaseUtil.checkDoubleIsNull(voucherDetailVo.getCurrencyDebit()));
                                voucherDetailVo.setCurrencyCredit(BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeCredit()) + BaseUtil.checkDoubleIsNull(voucherDetailVo.getCurrencyCredit()));
                            }
                        }
                    }
                });
                item.put("summary", summary);
            }
            data.add(item);
        }
        return data;
    }

    private Subject copySubject(Subject subject) {
        Subject copySubject = new Subject();
        copySubject.setCode(subject.getCode());
        copySubject.setBalanceDirection(subject.getBalanceDirection());
        copySubject.setCurrencyAccounting(subject.getCurrencyAccounting());
        copySubject.setId(subject.getId());
        copySubject.setLevel(subject.getLevel());
        copySubject.setName(subject.getName());
        copySubject.setParentId(subject.getParentId());
        copySubject.setUnit(subject.getUnit());
        return copySubject;
    }

    private VoucherDetailVo copyVoucherDetailVo1(VoucherDetailVo voucherDetailVo) {

        VoucherDetailVo vo = new VoucherDetailVo();
        vo.setVoucherId(voucherDetailVo.getVoucherId());
        vo.setDetailsId(voucherDetailVo.getDetailsId());
        vo.setWord(voucherDetailVo.getWord());
        vo.setCode(voucherDetailVo.getCode());
        vo.setSummary("本期合计");
        vo.setSubjectName(voucherDetailVo.getSubjectName());
        vo.setVoucherWordCode(voucherDetailVo.getVoucherWordCode());
        vo.setSubjectId(voucherDetailVo.getSubjectId());
        vo.setSubjectCode(voucherDetailVo.getSubjectCode());
        vo.setDetailSubjectCode(voucherDetailVo.getDetailSubjectCode());
        vo.setDebitAmount(voucherDetailVo.getDebitAmount());
        vo.setCreditAmount(voucherDetailVo.getCreditAmount());
        vo.setBalanceDirection(voucherDetailVo.getBalanceDirection());
        vo.setBalance(voucherDetailVo.getBalance());
        vo.setNum(voucherDetailVo.getNum());
        vo.setNumBalance(voucherDetailVo.getNumBalance());
        vo.setPrice(voucherDetailVo.getPrice());
        vo.setUnit(voucherDetailVo.getUnit());
        vo.setAuxiliaryTitle(voucherDetailVo.getAuxiliaryTitle());
        vo.setCurrencyDebit(voucherDetailVo.getCurrencyDebit());
        vo.setCurrencyCredit(voucherDetailVo.getCurrencyCredit());
        vo.setCurrencyBalance(voucherDetailVo.getCurrencyBalance());
        vo.setCumulativeCredit(voucherDetailVo.getCumulativeCredit());
        vo.setCumulativeDebit(voucherDetailVo.getCumulativeDebit());
        vo.setVoucherDate(voucherDetailVo.getVoucherDate());
        return vo;

    }

    /**
     * 获取期间结转科目总和
     *
     * @param accountSetsId
     * @param years
     * @param month
     * @param code
     * @return
     */
    @Override
    public Map<String, VoucherDetails> carryForwardMoney(Integer accountSetsId, Integer years, Integer month, String[] code) {

        Map<String, VoucherDetails> msv = new HashMap<>(code.length);
        for (String s : code) {
            VoucherDetails details = this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, s + "%");
            msv.put(s, details);
        }
        return msv;
    }

    @Override
    public Map<Integer, Double> closingCarryover(Integer accountSetsId, Integer years, Integer month) {
        //第一类前三个科目
        Map<Integer, Double> msv = new HashMap<>(8);
        msv.put(0, DoubleValueUtil.getNotNullVal(this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "2211%").getCreditAmount()));
        msv.put(10, this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "1602%").getCreditAmount());
        msv.put(20, this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "1802%").getCreditAmount());
        //第一类第四个科目
        msv.put(30,this.detailsMapper.selectCarryForwardMoneyByFourParm(accountSetsId, years, month).getCreditAmount());
        //第二类
        msv.put(40,this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "222101" + "%").getCreditAmount());

        //计提税金取数
        CheckOutSetBean bean = checkoutMapper.selectCheckoutSet(accountSetsId,years,month);
        if (bean == null){
            bean.setTaxRateOne(7.0);
            bean.setTaxRateTwo(3.0);
            bean.setTaxRateThree(2.0);
            bean.setTaxRateFour(25.0);
        }
        VoucherDetails valueDddedTax = this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "2221001%");
        Double a = 0d;
        if (valueDddedTax != null){
            a = DoubleValueUtil.getNotNullVal(valueDddedTax.getCreditAmount())-DoubleValueUtil.getNotNullVal(valueDddedTax.getDebitAmount());
            if (a<0){
                a = 0.0;
            }
        }
        VoucherDetails consumptionTaxPayable = this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "2221003%");
        Double b = 0d;
        if (consumptionTaxPayable != null){
            b = DoubleValueUtil.getNotNullVal(consumptionTaxPayable.getCreditAmount())-DoubleValueUtil.getNotNullVal(consumptionTaxPayable.getDebitAmount());
            if (b<0){
                b = 0.0;
            }
        }
        VoucherDetails businessTaxPayable = this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "2221004%");
        Double c = 0d;
        if (businessTaxPayable != null){
            c = DoubleValueUtil.getNotNullVal(businessTaxPayable.getCreditAmount())-DoubleValueUtil.getNotNullVal(businessTaxPayable.getDebitAmount());
            if (c<0){
                c = 0.0;
            }
        }
        msv.put(50,a*bean.getTaxRateOne()*0.01+b*bean.getTaxRateTwo()*0.01+c*bean.getTaxRateThree()*0.01);
        msv.put(51,a+b+c);
        //计提所得税
        Integer lrId = allSelectMapper.selectLirunReport(accountSetsId,"利润表");
        List<ReportTemplateItems> lrlist = allSelectMapper.selectReportTemplateItemsById(lrId);
        Long lrIdLong = new Long((long)lrId);
        String timeStart = years+month+"01";
        String timeEnd = years+month+"31";
        Map<Integer, ReportDataVo> lrMap = reportTemplateService.viewReport(accountSetsId,lrIdLong,timeStart,timeEnd);
        Integer a1 = 0;
        Double totalProfit = 0d;
        for (int i = 0; i < lrlist.size(); i++) {
            if (lrlist.get(i).getTitle().equals("货币资金")){
                a1 = lrlist.get(i).getId();
            }
        }
        if (lrMap.get(a1).getCurrentPeriodAmount()!=null){
            totalProfit = lrMap.get(a1).getCurrentPeriodAmount();
        }
        Double taxPayable = DoubleValueUtil.getNotNullVal(this.detailsMapper.selectCarryForwardMoney(accountSetsId, years, month, "2221004%").getCreditAmount());
        msv.put(61,totalProfit);
        msv.put(62,taxPayable);
        if (totalProfit<0){
            msv.put(60,0.0);
        }else {
            Double a2 = totalProfit*0.25 - taxPayable;
            if (a2<0){
                msv.put(60,0.0);
            }else {
                msv.put(60,a2);
            }
        }
        msv.put(70,this.detailsMapper.selectCarryForward(accountSetsId,timeStart,timeEnd));
        return msv;
    }

    @Override
    public List<AccountBookNumVo> generalLedgerByParamNum(Integer accountSetsId,String startTime, String endTime, String startSubject, String endSubject, Integer startLevel, Integer endLevel, Integer currencyId) {
        //条件查询
        List<AccountBookNumVo> accountBookNumVos = detailsMapper.generalLedgerByParamNum1(accountSetsId, startTime, endTime, startSubject, endSubject, startLevel, endLevel, currencyId,true);
        if (accountBookNumVos == null || accountBookNumVos.size() == 0){
            return null;
        }
        List<AccountBookNumVo> readyAddList =new ArrayList<>();
        List<String> list = new ArrayList<>();//排序用的列表
        Map<String, AccountBookNumVo> map = accountBookNumVos.stream().collect(Collectors.toMap(v->v.getSubjectId()+v.getVoucherDate(),accountBookNumVo->accountBookNumVo));

        HashMap<Integer, String> hashMap = new HashMap<>();
        accountBookNumVos.forEach(accountBookNumVo -> hashMap.put(accountBookNumVo.getSubjectId(),accountBookNumVo.getSubjectId()+accountBookNumVo.getVoucherDate()));


        //需要计算这些科目的余额
        Set<Integer> subjectSet = hashMap.keySet();
        List<String> monthBetweenDate = cn.gson.financial.kernel.utils.DateUtil.getMonthBetweenDate(startTime, endTime);
        for (String yearMonth : monthBetweenDate) {
            Date lastMonthEndTime = cn.gson.financial.kernel.utils.DateUtil.getLastMonthEndTime(cn.gson.financial.kernel.utils.DateUtil.parseDate(yearMonth, "yyyy-MM"));
            String lastMonthEndTimeString = cn.gson.financial.kernel.utils.DateUtil.formatDate(lastMonthEndTime, "yyyy-MM-dd");
            List<AccountBookNumVo> balanceVos = detailsMapper.countBalance1(accountSetsId,lastMonthEndTimeString,endTime, yearMonth, subjectSet);

            for (AccountBookNumVo balanceVo : balanceVos) {
                list.add(balanceVo.getSubjectId()+balanceVo.getVoucherDate());
                AccountBookNumVo vo = map.get(balanceVo.getSubjectId() + balanceVo.getVoucherDate());
                if (vo != null) {
                    balanceVo.setDebitAmount(vo.getDebitAmount());
                    balanceVo.setDebitNum(vo.getDebitNum());
                    balanceVo.setCreditAmount(vo.getCreditAmount());
                    balanceVo.setCreditNum(vo.getCreditNum());
                    balanceVo.setCurrencyDebit(vo.getCurrencyDebit());
                    balanceVo.setCurrencyCredit(vo.getCurrencyCredit());
                    balanceVo.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) + BaseUtil.checkDoubleIsNull(balanceVo.getDebitAmount()) - BaseUtil.checkDoubleIsNull(vo.getCreditAmount()));
                    balanceVo.setBalanceNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum()) + BaseUtil.checkDoubleIsNull(vo.getDebitNum()) - BaseUtil.checkDoubleIsNull(vo.getCreditNum()));
                    balanceVo.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()) + BaseUtil.checkDoubleIsNull(vo.getCurrencyDebit()) - BaseUtil.checkDoubleIsNull(vo.getCurrencyCredit()));
                }
                if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) < 0){
                    balanceVo.setBalanceDirection(balanceVo.getBalanceDirection().equals("借")?"贷":"借");
                    balanceVo.setBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    balanceVo.setCurrencyBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                } else if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) == 0){
                    balanceVo.setBalanceDirection("平");
                    balanceVo.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    balanceVo.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }else {
                    balanceVo.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    balanceVo.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }
            }
            readyAddList.addAll(balanceVos);
        }

        //排序
        Collections.sort(list);
        List<AccountBookNumVo> resultData = new ArrayList<>();
        list.forEach(value->{
            readyAddList.forEach(accountBookNumVo -> {
                if ((accountBookNumVo.getSubjectId()+accountBookNumVo.getVoucherDate()).equals(value)){
                    resultData.add(accountBookNumVo);
                }
            });
        });
        return resultData;
    }

    public List<Map<String, Object>> generalLedgerByParamNew(Integer accountSetsId, String startTime, String endTime, String startSubject, String endSubject, Integer startLevel, Integer endLevel, Integer currencyId,boolean showNumPrice){

        //当前查询账套
        AccountSets accountSets = accountSetsMapper.selectById(accountSetsId);
        //条件查询
        List<AccountBookNumVo> accountBookNumVos = detailsMapper.generalLedgerByParamNum1(accountSetsId, startTime, endTime, startSubject, endSubject, startLevel, endLevel, currencyId,showNumPrice);
        if (accountBookNumVos == null || accountBookNumVos.size() == 0){
            return null;
        }
        List<String> list = new ArrayList<>();//排序用的列表
        Map<String, AccountBookNumVo> map = accountBookNumVos.stream().collect(Collectors.toMap(v->v.getSubjectId()+v.getVoucherDate(),accountBookNumVo->accountBookNumVo));

        HashMap<Integer, String> hashMap = new HashMap<>();
        accountBookNumVos.forEach(accountBookNumVo -> hashMap.put(accountBookNumVo.getSubjectId(),accountBookNumVo.getSubjectId()+accountBookNumVo.getVoucherDate()));
        List<VoucherDetailVo> voucherDetailVoList = new ArrayList<>();

        //需要计算这些科目的余额
        Set<Integer> subjectSet = hashMap.keySet();
        HashMap<String, Double>  accumulatedThisYearMap  = new HashMap<>();
        List<String> monthBetweenDate = cn.gson.financial.kernel.utils.DateUtil.getMonthBetweenDate(startTime, endTime);
        for (String yearMonth : monthBetweenDate) {
            Date lastMonthEndTime = cn.gson.financial.kernel.utils.DateUtil.getLastMonthEndTime(cn.gson.financial.kernel.utils.DateUtil.parseDate(yearMonth, "yyyy-MM"));
            String lastMonthEndTimeString = cn.gson.financial.kernel.utils.DateUtil.formatDate(lastMonthEndTime, "yyyy-MM-dd");
            List<AccountBookNumVo> balanceVos = detailsMapper.countBalance1(accountSetsId, lastMonthEndTimeString,endTime, yearMonth, subjectSet);

            for (AccountBookNumVo balanceVo : balanceVos) {
                list.add(balanceVo.getSubjectId()+balanceVo.getVoucherDate());
                AccountBookNumVo vo = map.get(balanceVo.getSubjectId() + balanceVo.getVoucherDate());
                //期初余额
                VoucherDetailVo voucherDetailVo1 = new VoucherDetailVo();
                voucherDetailVo1.setSubjectId(balanceVo.getSubjectId());
                voucherDetailVo1.setSubjectCode(balanceVo.getFfsSubjectCode());
                voucherDetailVo1.setSubjectName(balanceVo.getFfsSubjectName());
                voucherDetailVo1.setCurrencyAccounting(balanceVo.getCurrencyAccounting());
                voucherDetailVo1.setUnit(balanceVo.getUnit());
                voucherDetailVo1.setSummary("期初余额");
                voucherDetailVo1.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(balanceVo.getVoucherDate(),"yyyy-MM"));
                voucherDetailVo1.setBalanceDirection(balanceVo.getBalanceDirection());
                voucherDetailVo1.setCreditAmount(0.0);
                voucherDetailVo1.setDebitAmount(0.0);
                voucherDetailVo1.setCurrencyCredit(0.0);
                voucherDetailVo1.setCurrencyDebit(0.0);
                //如果unit不为空，就看有没有具体的数量
                if (!BaseUtil.checkValueIsNull(voucherDetailVo1.getUnit()).equals("")){
                    //这里num仅仅为了方便前端是否置灰“显示数量金额”这个按钮
                    voucherDetailVo1.setNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum())+BaseUtil.checkDoubleIsNull(balanceVo.getCreditNum())+BaseUtil.checkDoubleIsNull(balanceVo.getDebitNum()));
                }

                if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance())<0){
                    voucherDetailVo1.setBalanceDirection(voucherDetailVo1.getBalanceDirection().equals("借")?"贷":"借");
                    voucherDetailVo1.setBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo1.setCurrencyBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }else if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) == 0){
                    voucherDetailVo1.setBalanceDirection("平");
                    voucherDetailVo1.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo1.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }else {
                    voucherDetailVo1.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo1.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }
                voucherDetailVoList.add(voucherDetailVo1);

                if (vo == null) {
                    //本期合计
                    VoucherDetailVo voucherDetailVo2 = new VoucherDetailVo();
                    voucherDetailVo2.setSubjectId(balanceVo.getSubjectId());
                    voucherDetailVo2.setSubjectCode(balanceVo.getFfsSubjectCode());
                    voucherDetailVo2.setSubjectName(balanceVo.getFfsSubjectName());
                    voucherDetailVo2.setUnit(balanceVo.getUnit());
                    voucherDetailVo2.setCurrencyAccounting(balanceVo.getCurrencyAccounting());
                    voucherDetailVo2.setSummary("本期合计");
                    voucherDetailVo2.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(balanceVo.getVoucherDate(),"yyyy-MM"));
                    voucherDetailVo2.setBalanceDirection(balanceVo.getBalanceDirection());
                    voucherDetailVo2.setCreditAmount(BaseUtil.checkDoubleIsNull(balanceVo.getCreditAmount()));
                    voucherDetailVo2.setDebitAmount(BaseUtil.checkDoubleIsNull(balanceVo.getDebitAmount()));
                    voucherDetailVo2.setCurrencyCredit(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyCredit()));
                    voucherDetailVo2.setCurrencyDebit(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyDebit()));
                    //如果unit不为空，就看有没有具体的数量
                    if (!BaseUtil.checkValueIsNull(voucherDetailVo2.getUnit()).equals("")){
                        //这里num仅仅为了方便前端是否置灰“显示数量金额”这个按钮
                        voucherDetailVo2.setNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum())+BaseUtil.checkDoubleIsNull(balanceVo.getCreditNum())+BaseUtil.checkDoubleIsNull(balanceVo.getDebitNum()));
                    }

                    if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance())<0){
                        voucherDetailVo2.setBalanceDirection(voucherDetailVo2.getBalanceDirection().equals("借")?"贷":"借");
                        voucherDetailVo2.setBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }else if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) == 0){
                        voucherDetailVo2.setBalanceDirection("平");
                        voucherDetailVo2.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }else {
                        voucherDetailVo2.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }
                    voucherDetailVoList.add(voucherDetailVo2);
                    //将本期的发生额记录下来，用于计算下一期的本年累计
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"creditAmount",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"creditAmount")) + voucherDetailVo2.getCreditAmount());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"debitAmount",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"debitAmount")) + voucherDetailVo2.getDebitAmount());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"currencyCredit",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyCredit")) + voucherDetailVo2.getCurrencyCredit());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"currencyDebit",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyDebit")) + voucherDetailVo2.getCurrencyDebit());

                }else {
                    //合并本期合计和余额
                    balanceVo.setDebitAmount(vo.getDebitAmount());
                    balanceVo.setDebitNum(vo.getDebitNum());
                    balanceVo.setCreditAmount(vo.getCreditAmount());
                    balanceVo.setCreditNum(vo.getCreditNum());
                    balanceVo.setCurrencyDebit(vo.getCurrencyDebit());
                    balanceVo.setCurrencyCredit(vo.getCurrencyCredit());

                    switch (balanceVo.getBalanceDirection()){
                        case "借":
                            balanceVo.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) + BaseUtil.checkDoubleIsNull(vo.getDebitAmount()) - BaseUtil.checkDoubleIsNull(vo.getCreditAmount()));
                            balanceVo.setBalanceNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum()) + BaseUtil.checkDoubleIsNull(vo.getDebitNum()) - BaseUtil.checkDoubleIsNull(vo.getCreditNum()));
                            balanceVo.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance())+ BaseUtil.checkDoubleIsNull(vo.getCurrencyDebit()) - BaseUtil.checkDoubleIsNull(vo.getCurrencyCredit()));
                            break;
                        case "贷":
                            balanceVo.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) + BaseUtil.checkDoubleIsNull(vo.getCreditAmount()) - BaseUtil.checkDoubleIsNull(vo.getDebitAmount()));
                            balanceVo.setBalanceNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum()) + BaseUtil.checkDoubleIsNull(vo.getCreditNum()) - BaseUtil.checkDoubleIsNull(vo.getDebitNum()));
                            balanceVo.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance())+ BaseUtil.checkDoubleIsNull(vo.getCurrencyCredit()) - BaseUtil.checkDoubleIsNull(vo.getCurrencyDebit()));
                            break;
                    }

                    //本期合计
                    VoucherDetailVo voucherDetailVo2 = new VoucherDetailVo();
                    voucherDetailVo2.setSubjectId(balanceVo.getSubjectId());
                    voucherDetailVo2.setSubjectCode(balanceVo.getFfsSubjectCode());
                    voucherDetailVo2.setSubjectName(balanceVo.getFfsSubjectName());
                    voucherDetailVo2.setUnit(balanceVo.getUnit());
                    voucherDetailVo2.setCurrencyAccounting(balanceVo.getCurrencyAccounting());
                    voucherDetailVo2.setSummary("本期合计");
                    voucherDetailVo2.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(balanceVo.getVoucherDate(),"yyyy-MM"));
                    voucherDetailVo2.setBalanceDirection(balanceVo.getBalanceDirection());
                    voucherDetailVo2.setCreditAmount(BaseUtil.checkDoubleIsNull(balanceVo.getCreditAmount()));
                    voucherDetailVo2.setDebitAmount(BaseUtil.checkDoubleIsNull(balanceVo.getDebitAmount()));
                    voucherDetailVo2.setCurrencyCredit(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyCredit()));
                    voucherDetailVo2.setCurrencyDebit(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyDebit()));
                    //如果unit不为空，就看有没有具体的数量
                    if (!BaseUtil.checkValueIsNull(voucherDetailVo2.getUnit()).equals("")){
                        //这里num仅仅为了方便前端是否置灰“显示数量金额”这个按钮
                        voucherDetailVo2.setNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum())+BaseUtil.checkDoubleIsNull(balanceVo.getCreditNum())+BaseUtil.checkDoubleIsNull(balanceVo.getDebitNum()));
                    }

                    if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance())<0){
                        voucherDetailVo2.setBalanceDirection(voucherDetailVo2.getBalanceDirection().equals("借")?"贷":"借");
                        voucherDetailVo2.setBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }else if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) == 0){
                        voucherDetailVo2.setBalanceDirection("平");
                        voucherDetailVo2.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }else {
                        voucherDetailVo2.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                        voucherDetailVo2.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                    }
                    voucherDetailVoList.add(voucherDetailVo2);
                    //将本期的发生额记录下来，用于计算下一期的本年累计
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"creditAmount",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"creditAmount")) + voucherDetailVo2.getCreditAmount());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"debitAmount",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"debitAmount")) + voucherDetailVo2.getDebitAmount());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"currencyCredit",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyCredit")) + voucherDetailVo2.getCurrencyCredit());
                    accumulatedThisYearMap.put(balanceVo.getSubjectId()+"currencyDebit",BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyDebit")) + voucherDetailVo2.getCurrencyDebit());
                }
                Double creditAmount = 0.0;
                Double debitAmount = 0.0;
                Double currencyDebit = 0.0;
                Double currencyCredit = 0.0;
                if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(yearMonth,"yyyy-MM")) == cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())){
                    //如果是本年累计的话  需要加上设置的期初//查询该科目设置的期初
                    VoucherDetailVo startDetail = baseMapper.findStartDetail(accountSetsId,balanceVo.getSubjectId());
                    if (startDetail!=null){
                        creditAmount = BaseUtil.checkDoubleIsNull(startDetail.getCumulativeCredit());
                        debitAmount = BaseUtil.checkDoubleIsNull(startDetail.getCumulativeDebit());
                        currencyDebit= BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeDebit());
                        currencyCredit = BaseUtil.checkDoubleIsNull(startDetail.getCurrencyCumulativeCredit());

                    }
                }
                //本年累计
                VoucherDetailVo voucherDetailVo3 = new VoucherDetailVo();
                voucherDetailVo3.setSubjectId(balanceVo.getSubjectId());
                voucherDetailVo3.setSubjectCode(balanceVo.getFfsSubjectCode());
                voucherDetailVo3.setSubjectName(balanceVo.getFfsSubjectName());
                voucherDetailVo3.setUnit(balanceVo.getUnit());
                voucherDetailVo3.setCurrencyAccounting(balanceVo.getCurrencyAccounting());
                voucherDetailVo3.setSummary("本年累计");
                voucherDetailVo3.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(balanceVo.getVoucherDate(),"yyyy-MM"));
                voucherDetailVo3.setBalanceDirection(balanceVo.getBalanceDirection());
                voucherDetailVo3.setCreditAmount(BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"creditAmount"))+creditAmount);
                voucherDetailVo3.setDebitAmount(BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"debitAmount")) +debitAmount);
                voucherDetailVo3.setCurrencyCredit(BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyCredit"))+currencyCredit);
                voucherDetailVo3.setCurrencyDebit(BaseUtil.checkDoubleIsNull(accumulatedThisYearMap.get(balanceVo.getSubjectId()+"currencyDebit"))+currencyDebit);
                //如果unit不为空，就看有没有具体的数量
                if (!BaseUtil.checkValueIsNull(voucherDetailVo3.getUnit()).equals("")){
                    //这里num仅仅为了方便前端是否置灰“显示数量金额”这个按钮
                    voucherDetailVo3.setNum(BaseUtil.checkDoubleIsNull(balanceVo.getBalanceNum())+BaseUtil.checkDoubleIsNull(balanceVo.getCreditNum())+BaseUtil.checkDoubleIsNull(balanceVo.getDebitNum()));
                }

                if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance())<0){
                    voucherDetailVo3.setBalanceDirection(voucherDetailVo3.getBalanceDirection().equals("借")?"贷":"借");
                    voucherDetailVo3.setBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo3.setCurrencyBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }else if (BaseUtil.checkDoubleIsNull(balanceVo.getBalance()) == 0){
                    voucherDetailVo3.setBalanceDirection("平");
                    voucherDetailVo3.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo3.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }else {
                    voucherDetailVo3.setBalance(BaseUtil.checkDoubleIsNull(balanceVo.getBalance()));
                    voucherDetailVo3.setCurrencyBalance(BaseUtil.checkDoubleIsNull(balanceVo.getCurrencyBalance()));
                }
                voucherDetailVoList.add(voucherDetailVo3);
            }
        }

        System.out.println(voucherDetailVoList.size());
        //排序
        Collections.sort(list);
        List<Map<String, Object>> data = new ArrayList<>();

        list.forEach(value->{
            Subject subject = new Subject();
            Map<String, Object> item = new HashMap<>(2);
            List<VoucherDetailVo>  summary = new ArrayList<>();

            voucherDetailVoList.forEach(voucherDetailVo -> {
                String  subjectIdVoucherDate = voucherDetailVo.getSubjectId()+ cn.gson.financial.kernel.utils.DateUtil.formatDate(voucherDetailVo.getVoucherDate(),"yyyy-MM");
                if (subjectIdVoucherDate.equals(value)){
                    subject.setId(voucherDetailVo.getSubjectId());
                    subject.setCode(voucherDetailVo.getSubjectCode());
                    subject.setName(voucherDetailVo.getSubjectName());
                    subject.setUnit(voucherDetailVo.getUnit());
                    subject.setCurrencyAccounting(voucherDetailVo.getCurrencyAccounting());
                    summary.add(voucherDetailVo);
                }
            });
            item.put("subject",subject);
            item.put("summary",summary);
            data.add(item);
        });
        return data;
    }


    private AccountBookNumVo copyAccountBookNumVo(AccountBookNumVo accountBookNumVo,String nextYearMonth) {
        AccountBookNumVo vo = new AccountBookNumVo();
        vo.setSubjectId(accountBookNumVo.getSubjectId());
        vo.setUnit(accountBookNumVo.getUnit());
        vo.setFfsSubjectCode(accountBookNumVo.getFfsSubjectCode());
        vo.setFfsSubjectName(accountBookNumVo.getFfsSubjectName());
        vo.setBalanceDirection(accountBookNumVo.getBalanceDirection());
        vo.setCurrencyName(accountBookNumVo.getCurrencyName());
        vo.setExchangeRate(accountBookNumVo.getExchangeRate());
        vo.setVoucherDate(nextYearMonth);
        vo.setDebitAmount(0.0);
        vo.setDebitNum(0.0);
        vo.setCreditAmount(0.0);
        vo.setCreditNum(0.0);
        vo.setCurrencyDebit(0.0);
        vo.setCurrencyCredit(0.0);
//        vo.setBalance(accountBookNumVo.getBalance());
//        vo.setBalanceNum(accountBookNumVo.getBalanceNum());
//        vo.setCurrencyBalance(accountBookNumVo.getCurrencyBalance());
        return vo;
    }

    /**
     * 核算项目明细账
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @param showNumPrice
     * @return
     */
    @Override
    public List<VoucherDetailVo> auxiliaryDetails(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Integer auxiliaryItemId, Boolean showNumPrice) {
        List<VoucherDetailVo> data = new ArrayList<>();
        //期初
        VoucherDetailVo startVo = getAuxiliaryStart(accountSetsId, auxiliaryId, accountDate, auxiliaryItemId);
        data.add(startVo);

        //明细
        List<VoucherDetailVo> detailVos = voucherDetailsAuxiliaryMapper.selectAccountBookDetails(accountSetsId, auxiliaryId, accountDate, auxiliaryItemId);
        //计算每次余额
        for (VoucherDetailVo vo : detailVos) {
            double b = 0d;
            switch (vo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount());
                    break;
            }
            vo.setBalance(startVo.getBalance() + b);
            startVo = vo;
        }

        data.addAll(detailVos);
        //本期统计
        VoucherDetailVo currentVo = getAuxiliaryCurrent(accountSetsId, auxiliaryId, accountDate, auxiliaryItemId, data.get(0));
        //年度统计
        VoucherDetailVo yearVo = getAuxiliaryYear(accountSetsId, auxiliaryId, accountDate, auxiliaryItemId);
        data.add(currentVo);
        data.add(yearVo);
        return data;
    }

    //ywh核算项目明细改
    public List<VoucherDetailVo> auxiliaryDetailsByParam3(Integer accountSetsId,Integer accountingCategoryId, Integer accountingCategoryDetailsId, String sTime, String eTime, String subjectCode, String auxiliaryTitle, Boolean showNumPrice){
        List<String> subCodeList = new ArrayList<>();
        List<VoucherDetailVo> resultDates = new ArrayList<>();
        // 对 科目进行 判断
        if(BaseUtil.checkValueIsNull(subjectCode).contains("-")){
            String[] sry = subjectCode.split("-");
            if (BaseUtil.isNumber(sry[0]) == false || BaseUtil.isNumber(sry[1]) == false ){
                new Exception("输入的科目编号有误");
                return null;
            }else {
                for (int i = Integer.parseInt(sry[0]); i <= Integer.parseInt(sry[1]); i++) {
                    subCodeList.add(String.valueOf(i));
                }
            }
        }else if(BaseUtil.checkValueIsNull(subjectCode).contains(",")){
            subCodeList = Arrays.asList(subjectCode.split(","));
        }else {
            if(!BaseUtil.checkValueIsNull(subjectCode).equals("")){
                subCodeList.add(subjectCode);
            }
        }
        System.out.println("subCodeList===" + subCodeList);
        //查询包含该辅助核算+该科目code的数据
        List<VoucherDetailVo>  voucherDetailVoList = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParamsYwh1(accountSetsId,accountingCategoryId,accountingCategoryDetailsId,showNumPrice,subCodeList);
        //有些科目没有设置期初，直接做了凭证，这里直接查询该凭证，数据全设置为0
        List<VoucherDetailVo>  removeList  = new ArrayList<>();
        voucherDetailVoList.forEach(voucherDetailVo -> {
            //删除不符合日期的数据
            if (voucherDetailVo.getVoucherDate() != null){
                if (!(cn.gson.financial.kernel.utils.DateUtil.parseDate(sTime,"yyyy-MM-dd").getTime() <=voucherDetailVo.getVoucherDate().getTime()
                        && voucherDetailVo.getVoucherDate().getTime() < cn.gson.financial.kernel.utils.DateUtil.parseDate(eTime,"yyyy-MM-dd").getTime())){
                    removeList.add(voucherDetailVo);
                }
            }
        });
        System.out.println("remove===" + removeList);
        voucherDetailVoList.removeAll(removeList);


        if (voucherDetailVoList == null || voucherDetailVoList.size() == 0){
            log.info("没有设置该辅助核算明细！");
            return null;
        }

        List<String> finalSubCodeList = subCodeList;
        List<String> dateList = cn.gson.financial.kernel.utils.DateUtil.getMonthBetweenDate(sTime, eTime);
        System.out.println("dateList===" + dateList);


        //当前查询账套
        AccountSets accountSets = accountSetsMapper.selectById(accountSetsId);
        for (VoucherDetailVo voucherDetailVo : voucherDetailVoList) {
            System.out.println(voucherDetailVo);
            //查询从账套创建到本月前所有的凭证的总额
            HashMap<String, Double> hashMap = voucherDetailsAuxiliaryMapper.selectBalance(accountSetsId, voucherDetailVo.getSubjectId(), accountingCategoryId, accountingCategoryDetailsId, sTime, showNumPrice, finalSubCodeList, voucherDetailVo.getDetailSubjectCode());
            Double balance = 0.0;
            Double num = 0.0;
            if (hashMap != null){
                balance = BaseUtil.checkDoubleIsNull(hashMap.get("balance"));
                num = BaseUtil.checkDoubleIsNull(hashMap.get("num"));
            }
            System.out.println("balance==="+ balance);
            if (voucherDetailVo.getCreditAmount() != null){
                balance += voucherDetailVo.getCreditAmount();
            }
            if (voucherDetailVo.getDebitAmount() != null){
                balance += voucherDetailVo.getDebitAmount();
            }
            System.out.println("加上期初的金额后balance==="+ balance);
            switch (voucherDetailVo.getBalanceDirection()){
                case "借":
                    num += BaseUtil.checkDoubleIsNull(voucherDetailVo.getNum());
                    break;
                case "贷":
                    num -= BaseUtil.checkDoubleIsNull(voucherDetailVo.getNum());
            }
            //根据期初中的辅助核算查询具体是哪个辅助核算，就算科目一样，也会不同的辅助核算；eg；查询条件是A，这时这个科目下期初查出了AB,AC,这时就需要将AB,AC全部展示出来
            for (String s : dateList) {
                String st = s+"-01";
                String et = s+ "-" + cn.gson.financial.kernel.utils.DateUtil.getDayOfMonth(cn.gson.financial.kernel.utils.DateUtil.parseDate(s+"-01"));
                //期初余额
                VoucherDetailVo voucherDetailVo1 = new VoucherDetailVo();
                voucherDetailVo1.setSummary("期初余额");
                voucherDetailVo1.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(st));
                voucherDetailVo1.setSubjectName(voucherDetailVo.getSubjectCode()+"-"+voucherDetailVo.getSubjectName());
                voucherDetailVo1.setNumBalance(BaseUtil.checkDoubleIsNull(num));
                voucherDetailVo1.setUnit(voucherDetailVo.getUnit());
                if (balance < 0){
                    voucherDetailVo1.setBalanceDirection(voucherDetailVo.getBalanceDirection().equals("借")?"贷":"借");
                    voucherDetailVo1.setBalance(-balance);
                }else if (balance == 0){
                    voucherDetailVo1.setBalanceDirection("平");
                    voucherDetailVo1.setBalance(0.0);
                }else {
                    voucherDetailVo1.setBalanceDirection(voucherDetailVo.getBalanceDirection().equals("借")?"借":"贷");
                    voucherDetailVo1.setBalance(balance);
                }
                resultDates.add(voucherDetailVo1);//加入期初余额

                //将凭证明细加进去
                Double currentBalance = balance;
                Double currentNum = num;
                Double creditNum = 0.0;
                Double debitNum = 0.0;

                //查询这期做的凭证数据
                List<VoucherDetailVo> voucherDetailVoAll = voucherDetailsAuxiliaryMapper.findVoucherDetails(accountSetsId, voucherDetailVo.getSubjectId(), accountingCategoryId, accountingCategoryDetailsId, st, et, showNumPrice);
                for (VoucherDetailVo detailVo : voucherDetailVoAll) {
                    if (voucherDetailVo.getSubjectId().equals(detailVo.getSubjectId())
                    ){
                        if (BaseUtil.checkDoubleIsNull(detailVo.getCreditAmount())==0 && BaseUtil.checkDoubleIsNull(detailVo.getDebitAmount())==0){
                            //说明本期没有做该凭证
                            detailVo.setBalance(currentBalance);//余额就是查询出来的余额
                            detailVo.setNumBalance(currentNum);//余额就是查询出来的余额
                        }else {
                            double b = 0d;
                            switch (voucherDetailVo.getBalanceDirection()) {
                                case "借":
                                    b = DoubleValueUtil.getNotNullVal(detailVo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(detailVo.getCreditAmount());
                                    break;
                                case "贷":
                                    b = DoubleValueUtil.getNotNullVal(detailVo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(detailVo.getDebitAmount());
                                    break;
                            }
                            detailVo.setBalance(currentBalance+b);
                        }
                        currentBalance = detailVo.getBalance();

                        //将凭证明细的数量设置给借贷方向的数量
                        if (BaseUtil.checkDoubleIsNull(detailVo.getCreditAmount()) != 0){
                            detailVo.setCumulativeCreditNum(BaseUtil.checkDoubleIsNull(detailVo.getNum()));
                            creditNum  += detailVo.getCumulativeCreditNum();
                            if(detailVo.getNum() != null){
                                detailVo.setNumBalance(currentNum - detailVo.getNum());
                            }
                        }
                        if (BaseUtil.checkDoubleIsNull(detailVo.getDebitAmount()) != 0 ){
                            detailVo.setCumulativeDebitNum(BaseUtil.checkDoubleIsNull(detailVo.getNum()));
                            debitNum  += detailVo.getCumulativeDebitNum();
                            if(detailVo.getNum() != null){
                                detailVo.setNumBalance(currentNum + detailVo.getNum());
                            }
                        }

                        if(currentBalance > 0){
                            detailVo.setBalance(currentBalance);
                        }else if (currentBalance == 0){
                            detailVo.setBalance(0.0);
                            detailVo.setBalanceDirection("平");
                        }else {
                            detailVo.setBalanceDirection(detailVo.getBalanceDirection().equals("借")?"贷":"借");
                            detailVo.setBalance(-currentBalance);
                            detailVo.setNumBalance(-BaseUtil.checkDoubleIsNull(detailVo.getNumBalance()));
                        }
                        detailVo.setSubjectName(detailVo.getSubjectCode()+detailVo.getSubjectName());

                        currentNum = BaseUtil.checkDoubleIsNull(detailVo.getNumBalance());
                        resultDates.add(detailVo);
                    }
                }

                //本期合计
                List<VoucherDetailVo> vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParamsYwh2(accountSetsId, voucherDetailVo.getSubjectId(),accountingCategoryId, accountingCategoryDetailsId, st, et, showNumPrice);
                VoucherDetailVo voucherDetailVo2 = vos.get(0);
                voucherDetailVo2.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(et));
                voucherDetailVo2.setSubjectName(voucherDetailVo.getSubjectCode()+"-"+voucherDetailVo.getSubjectName());
                voucherDetailVo2.setUnit(voucherDetailVo.getUnit());
                voucherDetailVo2.setPrice(null);
                voucherDetailVo2.setBalanceDirection(voucherDetailVo2.getBalanceDirection() == null?voucherDetailVo.getBalanceDirection():voucherDetailVo2.getBalanceDirection());
                voucherDetailVo2.setCumulativeDebitNum(debitNum);
                voucherDetailVo2.setCumulativeCreditNum(creditNum);
                System.out.println("voucherDetailVo2==="  + voucherDetailVo2 );
                if (voucherDetailVo2.getCreditAmount()==0 &&voucherDetailVo2.getDebitAmount()==0){
                    //说明本期没有做该凭证
                    voucherDetailVo2.setBalance(balance);//余额就是查询出来的余额
                    voucherDetailVo2.setNumBalance(num);//余额就是查询出来的余额

                }else {
                    double b = 0d;
                    switch (voucherDetailVo.getBalanceDirection()) {
                        case "借":
                            b = DoubleValueUtil.getNotNullVal(voucherDetailVo2.getDebitAmount()) - DoubleValueUtil.getNotNullVal(voucherDetailVo2.getCreditAmount());
                            if(voucherDetailVo2.getNum() != null){
                                voucherDetailVo2.setNumBalance(num + voucherDetailVo2.getNum());
                            }
                            break;
                        case "贷":
                            b = DoubleValueUtil.getNotNullVal(voucherDetailVo2.getCreditAmount()) - DoubleValueUtil.getNotNullVal(voucherDetailVo2.getDebitAmount());
                            if(voucherDetailVo2.getNum() != null){
                                voucherDetailVo2.setNumBalance(num + voucherDetailVo2.getNum());
                            }
                            break;
                    }
                    voucherDetailVo2.setBalance(balance+b);
                    voucherDetailVo2.setWord(voucherDetailVo2.getWord()+"-"+voucherDetailVo2.getCode());
                }

                if (voucherDetailVo2.getBalance() < 0){
                    voucherDetailVo2.setBalanceDirection(voucherDetailVo.getBalanceDirection().equals("借")?"贷":"借");
                    voucherDetailVo2.setBalance(-BaseUtil.checkDoubleIsNull(voucherDetailVo2.getBalance()));
                    voucherDetailVo2.setNumBalance(-BaseUtil.checkDoubleIsNull(voucherDetailVo2.getNumBalance()));
                }else if (voucherDetailVo2.getBalance() == 0){
                    voucherDetailVo2.setBalanceDirection("平");
                    voucherDetailVo2.setBalance(0.0);
                }else {
                    voucherDetailVo2.setBalance(BaseUtil.checkDoubleIsNull(voucherDetailVo2.getBalance()));
                }

                resultDates.add(voucherDetailVo2);//加入本期合计

                //本年累计
                VoucherDetailVo voucherDetailVo3 = vos.get(1);
                voucherDetailVo3.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.parseDate(et));
                voucherDetailVo3.setSubjectName(voucherDetailVo.getSubjectCode()+"-"+voucherDetailVo.getSubjectName());
                voucherDetailVo3.setUnit(voucherDetailVo.getUnit());
                voucherDetailVo3.setPrice(null);
                voucherDetailVo3.setBalanceDirection(voucherDetailVo3.getBalanceDirection() == null?voucherDetailVo.getBalanceDirection():voucherDetailVo3.getBalanceDirection());
                voucherDetailVo3.setCumulativeDebitNum(debitNum);
                voucherDetailVo3.setCumulativeCreditNum(creditNum);
                //如果是本年的话就需要把加上期初的借贷放累计金额
                System.out.println("cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(s,\"yyyy-MM\")==="+cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(s,"yyyy-MM")));
                System.out.println("cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())===" + cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate()));
                if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(s,"yyyy-MM")) == cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())){
                    voucherDetailVo3.setCreditAmount(BaseUtil.checkDoubleIsNull(voucherDetailVo.getCumulativeCredit())+voucherDetailVo3.getCreditAmount());
                    voucherDetailVo3.setDebitAmount(BaseUtil.checkDoubleIsNull(voucherDetailVo.getCumulativeDebit())+ voucherDetailVo3.getDebitAmount());
                }
                voucherDetailVo3.setBalanceDirection(voucherDetailVo2.getBalanceDirection());
                voucherDetailVo3.setBalance(BaseUtil.checkDoubleIsNull(voucherDetailVo2.getBalance()));
                voucherDetailVo3.setNumBalance(BaseUtil.checkDoubleIsNull(voucherDetailVo2.getNumBalance()));

                //加入期初的数量
                if (cn.gson.financial.kernel.utils.DateUtil.getYear(cn.gson.financial.kernel.utils.DateUtil.parseDate(s,"yyyy-MM")) == cn.gson.financial.kernel.utils.DateUtil.getYear(accountSets.getEnableDate())){
                    voucherDetailVo3.setCumulativeDebitNum(BaseUtil.checkDoubleIsNull(voucherDetailVo.getCumulativeDebitNum()) + BaseUtil.checkDoubleIsNull(voucherDetailVo3.getCumulativeDebitNum()));
                    voucherDetailVo3.setCumulativeCreditNum(BaseUtil.checkDoubleIsNull(voucherDetailVo.getCumulativeCreditNum()) +  BaseUtil.checkDoubleIsNull(voucherDetailVo3.getCumulativeCreditNum()));
                }
                resultDates.add(voucherDetailVo3);//加入本年累计

                balance = BaseUtil.checkDoubleIsNull(voucherDetailVo2.getBalance());//balance需要加上本期的余额
                num = BaseUtil.checkDoubleIsNull(voucherDetailVo2.getNumBalance());//balance需要加上本期的余额
            }
        }
        return resultDates;
    }

    private VoucherDetailVo copyVoucherDetailVo(VoucherDetailVo voucherDetailVo) {
        VoucherDetailVo vo = new VoucherDetailVo();
        vo.setCreditAmount(0.0);
        vo.setDebitAmount(0.0);
        vo.setCumulativeDebit(0.0);
        vo.setCumulativeCredit(0.0);
        vo.setSubjectId(voucherDetailVo.getSubjectId());
        vo.setSubjectCode(voucherDetailVo.getSubjectCode());
        vo.setSubjectName(voucherDetailVo.getSubjectName());
        vo.setWord(voucherDetailVo.getWord());
        vo.setCode(voucherDetailVo.getCode());
        vo.setBalanceDirection(voucherDetailVo.getBalanceDirection());
        vo.setSummary(voucherDetailVo.getSummary());
        vo.setVoucherDate(null);
        vo.setDetailSubjectCode(voucherDetailVo.getDetailSubjectCode());
        vo.setVoucherWordCode(voucherDetailVo.getVoucherWordCode());
//        vo.setNum(voucherDetailVo.getNum());
        vo.setNum(null);
        vo.setUnit(null);

        return vo;
    }


    /**
     * 核算项目明细账 ----动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param
     * @param auxiliaryItemId
     * @param showNumPrice
     * @return
     */
    @Override
    public List<VoucherDetailVo> auxiliaryDetailsByParam2(Integer accountSetsId, Integer auxiliaryId, Date sTime,Date eTime ,String subjectCode, Integer auxiliaryItemId, Boolean showNumPrice) {
        String sSubjectCode="";
        String eSubjectCode="";
        List<String> subCodeList = new ArrayList<>();
        // 对 科目进行 判断
        if(BaseUtil.checkValueIsNull(subjectCode).contains("-")){
            String[] sry = subjectCode.split("-");
            sSubjectCode = sry[0];
            eSubjectCode = sry[1];
        }else if(BaseUtil.checkValueIsNull(subjectCode).contains(",")){
            String[] sry = subjectCode.split(",");
            subCodeList.add(sry[0]);
            subCodeList.add(sry[1]);
        }else {
            if(!BaseUtil.checkValueIsNull(subjectCode).equals("")){
                subCodeList.add(subjectCode);
            }
        }
        List<VoucherDetailVo> data = new ArrayList<>();

        VoucherDetailVo startVo = null;

        //期初
        startVo = this.getAuxiliaryStartByParam(accountSetsId, auxiliaryId, true,eTime, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

        data.add(startVo);

        //明细
        List<VoucherDetailVo> detailVos =
        voucherDetailsAuxiliaryMapper.selectAccountBookDetailsByParams(accountSetsId, auxiliaryId,sTime,eTime , auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

        System.out.println("detailVos--> 12312 : " + detailVos);
        //计算每次余额
        for (VoucherDetailVo vo : detailVos) {
            double b = 0d;
            double nb = 0d;
            switch (vo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                    if(vo.getNum() != null){
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) + vo.getNum());
                    }else {
                        vo.setNumBalance(startVo.getNumBalance());
                    }
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount());
                    if(vo.getNum() != null){
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - vo.getNum());
                    }else {
                        vo.setNumBalance(startVo.getNumBalance());
                    }
                    break;
            }
            vo.setSubjectName(vo.getSubjectCode()+"-"+vo.getSubjectName());
            vo.setBalance(startVo.getBalance()+b);
            vo.setWord(vo.getWord()+"-"+vo.getCode());
            startVo = vo;
        }

        data.addAll(detailVos);
        //本期统计
        VoucherDetailVo currentVo = getAuxiliaryCurrentByParam2(accountSetsId, auxiliaryId, sTime, eTime, auxiliaryItemId, sSubjectCode, eSubjectCode, showNumPrice, subCodeList, data.get(0));

        if(currentVo.getBalance() == null){
            currentVo.setBalance(startVo.getBalance());
        }

        //年度统计
        VoucherDetailVo yearVo = getAuxiliaryYearByParam(accountSetsId, auxiliaryId, eTime, auxiliaryItemId, sSubjectCode, eSubjectCode, showNumPrice, subCodeList);

        if(startVo.getBalance() == 0
                && currentVo.getBalance() == 0
                && yearVo.getBalance() == 0){
            return new ArrayList<>();
        }
        data.add(currentVo);
        data.add(yearVo);
        return data;
    }


    /**
     * 获取期初统计  -配合动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryStartByParam(Integer accountSetsId, Integer auxiliaryId,boolean flag, Date accountDate, Integer auxiliaryItemId,String sSubjectCode,String eSubjectCode,boolean showNumPrice,List<String> subCodeList) {
        //当前查询账套
        AccountSets accountSets = accountSetsMapper.selectById(accountSetsId);
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams2(accountSetsId, auxiliaryId, null, accountDate, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

        VoucherDetailVo startVo = new VoucherDetailVo();
        startVo.setSummary("期初余额");
        startVo.setVoucherDate(cn.gson.financial.kernel.utils.DateUtil.getFirstDateOfMonth(accountDate));


        startVo.setBalance(0d);
        startVo.setBalanceDirection("平");
        startVo.setNumBalance(0d);

        if (startVos != null && !startVos.isEmpty()) {
            if (startVos.get(0) != null) {
                VoucherDetailVo vo = startVos.get(0);
                startVo.setBalanceDirection(vo.getBalanceDirection());
                switch (vo.getBalanceDirection()) {
                    case "借":
                        startVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        if(vo.getNum() != null){
                            startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) + DoubleValueUtil.getNotNullVal(vo.getNum()));
                        }else {
                            startVo.setNumBalance(0d);
                        }
                        break;
                    case "贷":
                        startVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        if(vo.getNum() != null){
                            startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getNum()));
                        }else {
                            startVo.setNumBalance(0d);
                        }
                        break;
                }
//                startVo.setCreditAmount(vo.getCreditAmount());
//                startVo.setDebitAmount(vo.getDebitAmount());
                startVo.setSubjectName(vo.getSubjectCode()+"-"+vo.getSubjectName());
                startVo.setSubjectCode(vo.getSubjectCode());
                startVo.setSubjectId(vo.getSubjectId());
//                startVo.setWord(vo.getWord()+ "-" + vo.getCode());
                if(showNumPrice){
                    startVo.setNum(vo.getNum());
                    startVo.setPrice(vo.getPrice());
                    startVo.setUnit(vo.getUnit());
                }

            }
        }
        List<VoucherDetailVo> voucherDetailVos = null;
        System.out.println("账套启用日期: " + DateFormatUtils.format(accountSets.getEnableDate(), "yyyyMM"));
        System.out.println("查询日期: " + DateFormatUtils.format(accountDate, "yyyyMM"));
        if(!DateFormatUtils.format(accountSets.getEnableDate(), "yyyyMM").equals(DateFormatUtils.format(accountDate, "yyyyMM"))){
            System.out.println("qwertyuiop");
            voucherDetailVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams3(accountSetsId, DateUtil.getMonthEnd(accountDate), auxiliaryItemId, sSubjectCode, eSubjectCode, showNumPrice, subCodeList);

            System.out.println("voucherDetailVos_rghjm: " + voucherDetailVos);

            if(voucherDetailVos != null && !voucherDetailVos.isEmpty()){
                if(voucherDetailVos.get(0) != null){
                    VoucherDetailVo vo = voucherDetailVos.get(0);
                    switch (vo.getBalanceDirection()) {
                        case "借":
                            startVo.setBalance(DoubleValueUtil.getNotNullVal(startVo.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));

                            startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) + DoubleValueUtil.getNotNullVal(vo.getNum()));

                            break;
                        case "贷":
                            startVo.setBalance(DoubleValueUtil.getNotNullVal(startVo.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));

                            startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getNum()));

                            break;
                    }
                }
            }
        }

        System.out.println("startVo: " + startVo);
        return startVo;
    }

    /**
     * 获取本期统计 --配合动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryCurrentByParam2(Integer accountSetsId, Integer auxiliaryId,Date st, Date et, Integer auxiliaryItemId,String sSubjectCode,String eSubjectCode,boolean showNumPrice,List<String> subCodeList, VoucherDetailVo startVo) {

        List<VoucherDetailVo>
                vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams(accountSetsId, auxiliaryId, st, et, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

//        System.out.println("vos: "+ vos);
        VoucherDetailVo currentVo = new VoucherDetailVo();
        currentVo.setSummary("本期合计");
        currentVo.setVoucherDate(et);
        currentVo.setBalance(0d);
        currentVo.setPrice(startVo.getPrice());
        currentVo.setBalanceDirection("平");
//        currentVo.setWord(startVo.getWord());

        if (vos != null && !vos.isEmpty() && vos.get(0) != null) {
            VoucherDetailVo vo = vos.get(0);
            //加上期初余额
            switch (vo.getBalanceDirection()) {
                case "借":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) + startVo.getBalance());
                    break;
                case "贷":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) + startVo.getBalance());
                    break;
            }
            currentVo.setCreditAmount(vo.getCreditAmount());
            currentVo.setDebitAmount(vo.getDebitAmount());
            if (!DoubleComparer.considerEqual(currentVo.getBalance(), 0d)) {
                currentVo.setBalanceDirection(vo.getBalanceDirection());
            }
            if(showNumPrice){
                switch (vo.getBalanceDirection()) {
                    case "借":
                        currentVo.setNumBalance(DoubleValueUtil.getNotNullVal(vo.getNumBalance()) + DoubleValueUtil.getNotNullVal(startVo.getNumBalance()));
                        break;
                    case "贷":
                        currentVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getNumBalance()));
                        break;
                }
            }
        }else{
            currentVo.setBalance(startVo.getBalance());
        }
        return currentVo;
    }



    /**
     * 获取本期统计 --配合动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryCurrentByParam(Integer accountSetsId, Integer auxiliaryId,boolean flag, Date accountDate, Integer auxiliaryItemId,String sSubjectCode,String eSubjectCode,boolean showNumPrice,List<String> subCodeList, VoucherDetailVo startVo) {

        List<VoucherDetailVo> vos = null;

        if (flag){
            vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams(accountSetsId, auxiliaryId, null, accountDate, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

        }else {
            vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams(accountSetsId, auxiliaryId, accountDate, null, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);
        }
//        System.out.println("vos: "+ vos);
        VoucherDetailVo currentVo = new VoucherDetailVo();
        currentVo.setSummary("本期合计");
        currentVo.setVoucherDate(accountDate);
        currentVo.setBalance(0d);
        currentVo.setPrice(startVo.getPrice());
        currentVo.setBalanceDirection("平");
//        currentVo.setWord(startVo.getWord());

        if (vos != null && !vos.isEmpty() && vos.get(0) != null) {
            VoucherDetailVo vo = vos.get(0);
            //加上期初余额
            switch (vo.getBalanceDirection()) {
                case "借":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) + startVo.getBalance());
                    break;
                case "贷":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) + startVo.getBalance());
                    break;
            }
            currentVo.setCreditAmount(vo.getCreditAmount());
            currentVo.setDebitAmount(vo.getDebitAmount());
            if (!DoubleComparer.considerEqual(currentVo.getBalance(), 0d)) {
                currentVo.setBalanceDirection(vo.getBalanceDirection());
            }
            if(showNumPrice){
                switch (vo.getBalanceDirection()) {
                    case "借":
                        currentVo.setNumBalance(DoubleValueUtil.getNotNullVal(vo.getNumBalance()) + DoubleValueUtil.getNotNullVal(startVo.getNumBalance()));
                        break;
                    case "贷":
                        currentVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getNumBalance()));
                        break;
                }
            }
        }
        return currentVo;
    }

    /**
     * 获取年度统计 ---配合动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryYearByParam(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Integer auxiliaryItemId,String sSubjectCode,String eSubjectCode,boolean showNumPrice,List<String> subCodeList) {
        //获取该辅助核算设置的期初
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParams2(accountSetsId, auxiliaryId, null, accountDate, auxiliaryItemId,sSubjectCode,eSubjectCode,showNumPrice,subCodeList);

        VoucherDetailVo startVo = new VoucherDetailVo();
        startVo.setBalance(0d);
        startVo.setNumBalance(0d);
        if (startVos != null && !startVos.isEmpty() && startVos.get(0) != null) {
            startVo = startVos.get(0);
            double b = 0d;
            switch (startVo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(startVo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(startVo.getCreditAmount());
                    if(startVo.getNum() != null){
                        startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) + startVo.getNum());
                    }
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(startVo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(startVo.getDebitAmount());
                    if(startVo.getNum() != null){
                        startVo.setNumBalance(DoubleValueUtil.getNotNullVal(startVo.getNumBalance()) - startVo.getNum());
                    }
                    break;
            }
            startVo.setBalance(b);
        }
        List<VoucherDetailVo> vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, DateUtil.getYearBegin(accountDate), DateUtil.getMonthEnd(accountDate), auxiliaryItemId);
        VoucherDetailVo yearVo = new VoucherDetailVo();
        yearVo.setSummary("本年累计");
        yearVo.setVoucherDate(accountDate);
        yearVo.setBalance(0d);
        yearVo.setBalanceDirection("平");

        System.out.println("vos==" + vos);
        System.out.println(vos != null);
        System.out.println(!vos.isEmpty());
        System.out.println( vos.get(0) != null);
        if (vos != null && !vos.isEmpty() && vos.get(0) != null) {
            System.out.println("iiiiiiiiiiiiii");
            VoucherDetailVo vo = vos.get(0);
            //加上期初余额
            double b = 0d;
            switch (vo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                    yearVo.setNumBalance(DoubleValueUtil.getNotNullVal(vo.getNumBalance()) + DoubleValueUtil.getNotNullVal(startVo.getNumBalance()));
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount());
                    yearVo.setNumBalance(DoubleValueUtil.getNotNullVal(vo.getNumBalance()) - DoubleValueUtil.getNotNullVal(startVo.getNumBalance()));
                    break;
            }
            yearVo.setBalance(b + startVo.getBalance());
            yearVo.setCreditAmount(vo.getCreditAmount());
            yearVo.setDebitAmount(vo.getDebitAmount());
            yearVo.setPrice(startVo.getPrice());
            yearVo.setWord(vo.getWord()+"-"+vo.getCode());


            if (!DoubleComparer.considerEqual(yearVo.getBalance(), 0d)) {
                yearVo.setBalanceDirection(vo.getBalanceDirection());
            }
        }else {
            System.out.println("ppppppppppp");
            yearVo.setBalance(startVo.getBalance());
        }
        System.out.println("yearVo=="+ yearVo);

//        VoucherDetails detailsMapperAuxiliary = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParamsYwh1(accountSetsId,auxiliaryId,auxiliaryItemId,showNumPrice,subCodeList);

        return yearVo;
    }





    /**
     * 获取期初统计
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryStart(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Integer auxiliaryItemId) {
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, null, DateUtil.getMonthBegin(accountDate), auxiliaryItemId);
        VoucherDetailVo startVo = new VoucherDetailVo();
        startVo.setSummary("期初余额");
        startVo.setVoucherDate(accountDate);
        startVo.setBalance(0d);
        startVo.setBalanceDirection("平");

        if (startVos != null && !startVos.isEmpty()) {
            if (startVos.get(0) != null) {
                VoucherDetailVo vo = startVos.get(0);
                startVo.setBalanceDirection(vo.getBalanceDirection());
                switch (vo.getBalanceDirection()) {
                    case "借":
                        startVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        break;
                    case "贷":
                        startVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        break;
                }
                startVo.setCreditAmount(vo.getCreditAmount());
                startVo.setDebitAmount(vo.getDebitAmount());
            }
        }
        return startVo;
    }

    /**
     * 获取本期统计
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryCurrent(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Integer auxiliaryItemId, VoucherDetailVo startVo) {
        List<VoucherDetailVo> vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, DateUtil.getMonthBegin(accountDate), DateUtil.getMonthEnd(accountDate), auxiliaryItemId);
        VoucherDetailVo currentVo = new VoucherDetailVo();
        currentVo.setSummary("本期合计");
        currentVo.setVoucherDate(accountDate);
        currentVo.setBalance(0d);
        currentVo.setBalanceDirection("平");

        if (vos != null && !vos.isEmpty() && vos.get(0) != null) {
            VoucherDetailVo vo = vos.get(0);
            //加上期初余额
            switch (vo.getBalanceDirection()) {
                case "借":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) + startVo.getBalance());
                    break;
                case "贷":
                    currentVo.setBalance(DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) + startVo.getBalance());
                    break;
            }
            currentVo.setCreditAmount(vo.getCreditAmount());
            currentVo.setDebitAmount(vo.getDebitAmount());
            if (!DoubleComparer.considerEqual(currentVo.getBalance(), 0d)) {
                currentVo.setBalanceDirection(vo.getBalanceDirection());
            }
        }
        return currentVo;
    }

    /**
     * 获取年度统计
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param auxiliaryItemId
     * @return
     */
    private VoucherDetailVo getAuxiliaryYear(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Integer auxiliaryItemId) {
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, null, DateUtil.getYearBegin(accountDate), auxiliaryItemId);
        VoucherDetailVo startVo = new VoucherDetailVo();
        startVo.setBalance(0d);
        if (startVos != null && !startVos.isEmpty() && startVos.get(0) != null) {
            startVo = startVos.get(0);
            double b = 0d;
            switch (startVo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(startVo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(startVo.getCreditAmount());
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(startVo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(startVo.getDebitAmount());
                    break;
            }
            startVo.setBalance(b);
        }
        List<VoucherDetailVo> vos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, DateUtil.getYearBegin(accountDate), DateUtil.getMonthEnd(accountDate), auxiliaryItemId);
        VoucherDetailVo yearVo = new VoucherDetailVo();
        yearVo.setSummary("本年累计");
        yearVo.setVoucherDate(accountDate);
        yearVo.setBalance(0d);
        yearVo.setBalanceDirection("平");

        if (vos != null && !vos.isEmpty() && vos.get(0) != null) {
            VoucherDetailVo vo = vos.get(0);
            //加上期初余额
            double b = 0d;
            switch (vo.getBalanceDirection()) {
                case "借":
                    b = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                    break;
                case "贷":
                    b = DoubleValueUtil.getNotNullVal(vo.getCreditAmount()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount());
                    break;
            }
            yearVo.setBalance(b + startVo.getBalance());
            yearVo.setCreditAmount(vo.getCreditAmount());
            yearVo.setDebitAmount(vo.getDebitAmount());

            if (!DoubleComparer.considerEqual(yearVo.getBalance(), 0d)) {
                yearVo.setBalanceDirection(vo.getBalanceDirection());
            }
        }
        return yearVo;
    }

    /**
     * 本期核算项目
     *
     * @param accountSetsId
     * @return
     */
    @Override
    public List<AccountingCategoryDetails> auxiliaryList(Integer accountSetsId, Integer auxiliaryId) {
        return voucherDetailsAuxiliaryMapper.selectByAccountBlock(accountSetsId, auxiliaryId);
    }

    /**
     * 辅助核算项目余额
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param accountDate
     * @param showNumPrice
     * @return
     */
    @Override
    public List<BalanceVo> auxiliaryBalance(Integer accountSetsId, Integer auxiliaryId, Date accountDate, Boolean showNumPrice) {
        //所有辅助项目
        List<AccountingCategoryDetailsVo> categoryDetails = voucherDetailsAuxiliaryMapper.selectByAccountBlock1(accountSetsId, auxiliaryId);
//        for (int i = 0; i < categoryDetails.size(); i++) {
//            String flag = voucherDetailsAuxiliaryMapper.selectUnit(categoryDetails.get(i).getId());
//            if (flag!=null && !flag.equals("")){
//                categoryDetails.get(i).setUnit("有");
//            }
//        }
        //转换成待计算的辅助项目
        Map<Integer, BalanceVo> maps = new HashMap<>(categoryDetails.size());
        categoryDetails.forEach(details -> {
            BalanceVo vo = new BalanceVo();
            vo.setName(details.getName());
            vo.setCode(details.getCode());
            vo.setAuxiliaryId(details.getId());
            maps.put(details.getId(), vo);
        });

        //期初
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, null, DateUtil.getMonthBegin(accountDate), null);
        startVos.forEach(startVo -> {
            if (maps.containsKey(startVo.getDetailsId())) {
                BalanceVo vo = maps.get(startVo.getDetailsId());
                vo.setBalanceDirection(startVo.getBalanceDirection());
                vo.setBeginningBalance(DoubleValueUtil.getNotNullVal(startVo.getDebitAmount(), startVo.getCreditAmount()));
            }
        });

        //本期
        List<VoucherDetailVo> currentVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatistical(accountSetsId, auxiliaryId, DateUtil.getMonthBegin(accountDate), DateUtil.getMonthEnd(accountDate), null);
        currentVos.forEach(currentVo -> {
            if (maps.containsKey(currentVo.getDetailsId())) {
                BalanceVo vo = maps.get(currentVo.getDetailsId());
                vo.setBalanceDirection(currentVo.getBalanceDirection());
                vo.setCurrentDebitAmount(currentVo.getDebitAmount());
                vo.setCurrentCreditAmount(currentVo.getCreditAmount());
            }
        });

        //计算期末余额
        BalanceVo aCombined = new BalanceVo();
        aCombined.setName("合计");

        for (BalanceVo balanceVo : maps.values()) {
            double endingData;
            switch (balanceVo.getBalanceDirection()) {
                case "借":
                    endingData = DoubleValueUtil.getNotNullVal(balanceVo.getBeginningDebitBalance()) - DoubleValueUtil.getNotNullVal(balanceVo.getBeginningCreditBalance())
                            + DoubleValueUtil.getNotNullVal(balanceVo.getCurrentDebitAmount()) - DoubleValueUtil.getNotNullVal(balanceVo.getCurrentCreditAmount());
                    break;
                default:
                    endingData = DoubleValueUtil.getNotNullVal(balanceVo.getBeginningCreditBalance()) - DoubleValueUtil.getNotNullVal(balanceVo.getBeginningDebitBalance())
                            + DoubleValueUtil.getNotNullVal(balanceVo.getCurrentCreditAmount()) - DoubleValueUtil.getNotNullVal(balanceVo.getCurrentDebitAmount());
                    break;
            }

            balanceVo.setEndingActiveBalance(endingData);

            aCombined.setBeginningCreditBalance(balanceVo.getBeginningCreditBalance());
            aCombined.setBeginningDebitBalance(balanceVo.getBeginningDebitBalance());
            aCombined.setCurrentCreditAmount(balanceVo.getCurrentCreditAmount());
            aCombined.setCurrentDebitAmount(balanceVo.getCurrentDebitAmount());
            aCombined.setEndingDebitBalance(balanceVo.getEndingDebitBalance());
            aCombined.setEndingCreditBalance(balanceVo.getEndingCreditBalance());
        }

        List<BalanceVo> collect = maps.values().stream().sorted(Comparator.comparing(BalanceVo::getCode)).collect(Collectors.toList());

        if (collect.size() > 0) {
            collect = collect.stream().filter(vo ->
                    (vo.getBeginningBalance() != null && vo.getBeginningBalance() != 0) ||
                            (vo.getEndingBalance() != null && vo.getEndingBalance() != 0) ||
                            (vo.getCurrentDebitAmount() != null && vo.getCurrentDebitAmount() != 0) ||
                            (vo.getCurrentCreditAmount() != null && vo.getCurrentCreditAmount() != 0)
            ).collect(Collectors.toList());
            collect.add(aCombined);
        }

        return collect;
    }



    /**
     * 辅助核算项目余额 --动态
     *
     * @param accountSetsId
     * @param auxiliaryId
     * @param
     * @param
     * @return
     */
    @Override
    public List<BalanceVo> auxiliaryBalanceByParam(Integer accountSetsId,String sTime,String eTime, String sSubjectCode, String eSubjectCode, Integer auxiliaryId,String detailsAuxiliaryId,List<String> subList,boolean showNumPrice) {

        //所有辅助项目
        List<AccountingCategoryDetailsVo> categoryDetails = voucherDetailsAuxiliaryMapper.selectByAccountBlock1(accountSetsId, auxiliaryId);
        System.out.println(categoryDetails);
        for (int i = 0; i < categoryDetails.size(); i++) {
            List<String> flag = voucherDetailsAuxiliaryMapper.selectUnit(categoryDetails.get(i).getId(),sTime,eTime);
            if (flag.size()>0){
                for (int j = 0; j < flag.size(); j++) {
                    if (flag.get(j)!=null && !flag.get(j).equals("")){
                        System.out.println("--------");
                        categoryDetails.get(i).setUnit("有");
                        }
                    }
                }
            }


        //转换成待计算的辅助项目
        Map<Integer, BalanceVo> maps = new HashMap<>(categoryDetails.size());
        categoryDetails.forEach(details -> {
            BalanceVo vo = new BalanceVo();
            vo.setName(details.getName());
            vo.setCode(details.getCode());
            vo.setAuxiliaryId(details.getId());
            vo.setUnit(details.getUnit());
            maps.put(details.getId(), vo);
        });


        Date lastMonthEndTime = cn.gson.financial.kernel.utils.DateUtil.getLastMonthEndTime(cn.gson.financial.kernel.utils.DateUtil.parseDate(sTime, "yyyy-MM-dd"));

        String lastMonthEndTimeString = cn.gson.financial.kernel.utils.DateUtil.formatDate(lastMonthEndTime, "yyyy-MM-dd");
        //期初
        List<VoucherDetailVo> startVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParam2(accountSetsId, auxiliaryId,showNumPrice,lastMonthEndTimeString);
        startVos.forEach(startVo -> {
            if (maps.containsKey(startVo.getDetailsId())) {
                BalanceVo vo = maps.get(startVo.getDetailsId());
                vo.setBalanceDirection(startVo.getBalanceDirection());
//                vo.setBeginningBalance(DoubleValueUtil.getNotNullVal(startVo.getDebitAmount(), startVo.getCreditAmount()));
                vo.setBeginningCreditBalance(startVo.getCreditAmount());
                vo.setBeginningDebitBalance(startVo.getDebitAmount());
                vo.setUnit(startVo.getUnit());
                // -- 改显示数量金额
                if(startVo.getBalanceDirection().equals("借")){
                    vo.setBeginningDebitAmountNum(startVo.getNum());
                }else if(startVo.getBalanceDirection().equals("贷")){
                    vo.setBeginningCreditAmountNum(startVo.getNum());
                }
            }
        });

        //本期
        List<VoucherDetailVo> currentVos = voucherDetailsAuxiliaryMapper.selectAccountBookStatisticalByParam(accountSetsId, auxiliaryId, sTime, eTime,sSubjectCode ,eSubjectCode,null,subList,showNumPrice);
        currentVos.forEach(currentVo -> {
            if (maps.containsKey(currentVo.getDetailsId())) {
                BalanceVo vo = maps.get(currentVo.getDetailsId());
                vo.setBalanceDirection(currentVo.getBalanceDirection());
                vo.setCurrentDebitAmount(currentVo.getDebitAmount());
                vo.setCurrentCreditAmount(currentVo.getCreditAmount());
                vo.setCurrentDebitAmountNum(BaseUtil.checkDoubleIsNull(currentVo.getCurrentDebitAmountNum()));
                vo.setCurrentCreditAmountNum(BaseUtil.checkDoubleIsNull(currentVo.getCurrentCreditAmountNum()));
                vo.setUnit(currentVo.getUnit());
            }
        });

        //计算期末余额
        BalanceVo aCombined = new BalanceVo();
        aCombined.setName("合计");

        for (BalanceVo balanceVo : maps.values()) {
            double endingData;
            if (balanceVo.getBalanceDirection() == null) {
                continue;
            }
            if(balanceVo.getBalanceDirection().equals("借")){
                endingData = DoubleValueUtil.getNotNullVal(balanceVo.getBeginningDebitBalance()) - DoubleValueUtil.getNotNullVal(balanceVo.getBeginningCreditBalance())
                        + DoubleValueUtil.getNotNullVal(balanceVo.getCurrentDebitAmount()) - DoubleValueUtil.getNotNullVal(balanceVo.getCurrentCreditAmount());
            }else {
                endingData = DoubleValueUtil.getNotNullVal(balanceVo.getBeginningCreditBalance()) - DoubleValueUtil.getNotNullVal(balanceVo.getBeginningDebitBalance())
                        + DoubleValueUtil.getNotNullVal(balanceVo.getCurrentCreditAmount()) - DoubleValueUtil.getNotNullVal(balanceVo.getCurrentDebitAmount());
            }

            balanceVo.setEndingActiveBalance1(endingData);
            //本期借贷数量
            if (showNumPrice) {
                //期初借方数量+本期借方数量-期初贷方数量-本期贷方数量
                Double endNum = DoubleValueUtil.getNotNullVal(balanceVo.getBeginningDebitAmountNum()) + DoubleValueUtil.getNotNullVal(balanceVo.getCurrentDebitAmountNum()) - DoubleValueUtil.getNotNullVal(balanceVo.getBeginningCreditAmountNum()) - DoubleValueUtil.getNotNullVal(balanceVo.getCurrentCreditAmountNum());
                if (endNum < 0) {
                    endNum = -endNum;
                }
                //如果期末借方金额不为0，就说明数据在借方
                if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalance()) != 0){
                    balanceVo.setEndingDebitBalanceNum(endNum);
                }
                if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalance()) != 0){
                    balanceVo.setEndingCreditBalanceNum(endNum);
                }
            }

            aCombined.setBeginningCreditBalance(balanceVo.getBeginningCreditBalance());
            aCombined.setBeginningDebitBalance(balanceVo.getBeginningDebitBalance());
            aCombined.setCurrentCreditAmount(balanceVo.getCurrentCreditAmount());
            aCombined.setCurrentDebitAmount(balanceVo.getCurrentDebitAmount());
            aCombined.setEndingDebitBalance(balanceVo.getEndingDebitBalance());
            aCombined.setEndingCreditBalance(balanceVo.getEndingCreditBalance());

            aCombined.setBeginningCreditAmountNum(BaseUtil.checkDoubleIsNull(balanceVo.getBeginningCreditAmountNum()));
            aCombined.setBeginningDebitAmountNum(BaseUtil.checkDoubleIsNull(balanceVo.getBeginningDebitAmountNum()));
            aCombined.setCurrentCreditAmountNum(BaseUtil.checkDoubleIsNull(balanceVo.getCurrentCreditAmountNum()));
            aCombined.setCurrentDebitAmountNum(BaseUtil.checkDoubleIsNull(balanceVo.getCurrentDebitAmountNum()));
            aCombined.setEndingDebitBalanceNum(BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalanceNum()));
            aCombined.setEndingCreditBalanceNum(BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalanceNum()));
        }

        List<BalanceVo> collect = maps.values().stream().sorted(Comparator.comparing(BalanceVo::getCode)).collect(Collectors.toList());

        if (collect.size() > 0) {
            collect = collect.stream().filter(vo ->
                    (vo.getBeginningBalance() != null && vo.getBeginningBalance() != 0) ||
                            (vo.getEndingBalance() != null && vo.getEndingBalance() != 0) ||
                            (vo.getCurrentDebitAmount() != null && vo.getCurrentDebitAmount() != 0) ||
                            (vo.getCurrentCreditAmount() != null && vo.getCurrentCreditAmount() != 0) ||
                            // --改 显示数量金额
                            (vo.getCurrentCreditAmountNum() != null && vo.getCurrentCreditAmountNum() != 0) ||
                            (vo.getCurrentDebitAmountNum() != null && vo.getCurrentDebitAmountNum() != 0)
            ).collect(Collectors.toList());
            collect.add(aCombined);
        }

        for (BalanceVo balanceVo : collect) {
            if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalance()) < 0){
                balanceVo.setEndingDebitBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalance()));
                balanceVo.setEndingCreditBalance(null);
            }
            if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalance()) < 0){
                balanceVo.setEndingCreditBalance(-BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalance()));
                balanceVo.setEndingDebitBalance(null);
            }

            if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalanceNum()) < 0){
                balanceVo.setEndingDebitBalanceNum(-BaseUtil.checkDoubleIsNull(balanceVo.getEndingCreditBalanceNum()));
                balanceVo.setEndingCreditBalanceNum(null);
            }
            if (BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalanceNum()) < 0){
                balanceVo.setEndingCreditBalanceNum(-BaseUtil.checkDoubleIsNull(balanceVo.getEndingDebitBalanceNum()));
                balanceVo.setEndingDebitBalanceNum(null);
            }
        }
        return collect;
    }

    /**
     * 首页收入利润图表数据
     *
     * @param accountSetsId
     * @param year
     * @return
     */
    @Override
    public List<Map<String, Object>> getHomeReport(Integer accountSetsId, Integer year) {
        return baseMapper.selectHomeReport(accountSetsId, year);
    }

    /**
     * 首页费用数据
     *
     * @param accountSetsId
     * @param year
     * @param month
     * @return
     */
    @Override
    public List<Map<String, Object>> getCostReport(Integer accountSetsId, int year, int month) {
        return baseMapper.selectHomeCostReport(accountSetsId, year, month);
    }

    /**
     * 首页现金数据
     *
     * @param accountSetsId
     * @param year
     * @param month
     * @return
     */
    @Override
    public List<Map<String, Object>> getCashReport(Integer accountSetsId, int year, int month) {
        return baseMapper.selectHomeCashReport(accountSetsId, year, month);
    }

    /**
     * 断号整理
     *
     * @param accountSetsId
     * @param year
     * @param month
     */
    @Override
    @Transactional
    public void finishingOffNo(Integer accountSetsId, Integer year, Integer month) {
        this.checkCheckOut(accountSetsId, year, month);

        List<Map<String, Object>> data = this.baseMapper.selectBrokenData(accountSetsId, year, month);
        //过滤出没有连续的凭证字类别
        List<Map<String, Object>> collect = data.stream().filter(map -> !map.get("total").equals(((Integer) map.get("code")).longValue())).collect(Collectors.toList());
        if (!collect.isEmpty()) {
            List<Voucher> updateVouchers = new ArrayList<>();
            collect.forEach(it -> {
                String word = (String) it.get("word");
                LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
                qw.eq(Voucher::getWord, word);
                qw.eq(Voucher::getAccountSetsId, accountSetsId);
                qw.eq(Voucher::getVoucherYear, year);
                qw.eq(Voucher::getVoucherMonth, month);
                qw.orderByAsc(Voucher::getCreateDate);
                List<Voucher> vouchers = this.baseMapper.selectList(qw);

                //重置 code
                int code = 1;
                for (Voucher voucher : vouchers) {
                    voucher.setCode(code);
                    code++;
                }
                updateVouchers.addAll(vouchers);
            });

            this.updateBatchById(updateVouchers);
        }
    }

    /**
     * 批量删除
     *
     * @param accountSetsId
     * @param checked
     */
    @Override
    public void batchDelete(Integer accountSetsId, Integer[] checked, Integer year, Integer month) {
        this.checkCheckOut(accountSetsId, year, month);

        LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
        qw.eq(Voucher::getAccountSetsId, accountSetsId);
        qw.eq(Voucher::getVoucherYear, year);
        qw.eq(Voucher::getVoucherMonth, month);
        qw.in(Voucher::getId, Arrays.asList(checked));

        this.baseMapper.delete(qw);
    }

    /**
     * 根据当前 Id 获取上一条 ID
     *
     * @param accountSetsId
     * @param currentId
     * @return
     */
    @Override
    public Integer getBeforeId(Integer accountSetsId, Integer currentId) {
        return this.baseMapper.selectBeforeId(accountSetsId, currentId);
    }

    /**
     * 根据当前 Id 获取下一条 ID
     *
     * @param accountSetsId
     * @param currentId
     * @return
     */
    @Override
    public Integer getNextId(Integer accountSetsId, Integer currentId) {
        return this.baseMapper.selectNextId(accountSetsId, currentId);
    }

    /**
     * 获取最近使用的摘要
     *
     * @param accountSetsId
     * @return
     */
    @Override
    public List<String> getTopSummary(Integer accountSetsId) {
        return this.detailsMapper.selectTopSummary(accountSetsId);
    }

    /**
     * 审核
     *
     * @param accountSetsId
     * @param checked
     * @param year
     * @param month
     */
    @Override
    public void audit(Integer accountSetsId, Integer[] checked, UserVo currentUser, Integer year, Integer month) {
        this.checkCheckOut(accountSetsId, year, month);
        LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
        qw.eq(Voucher::getAccountSetsId, accountSetsId);
        qw.eq(Voucher::getVoucherYear, year);
        qw.eq(Voucher::getVoucherMonth, month);
        qw.in(Voucher::getId, Arrays.asList(checked));
        qw.isNull(Voucher::getAuditMemberId);
        List<Voucher> vouchers = baseMapper.selectList(qw);
        if (!vouchers.isEmpty()) {
            vouchers.forEach(voucher -> {
                voucher.setAuditMemberId(currentUser.getId());
                voucher.setAuditMemberName(currentUser.getRealName());
                voucher.setAuditDate(new Date());
                voucher.setState("已审核");
            });
            this.updateBatchById(vouchers);
        }
    }

    /**
     * 反审核
     *
     * @param accountSetsId
     * @param checked
     * @param year
     * @param month
     */
    @Override
    public void cancelAudit(Integer accountSetsId, Integer[] checked, UserVo currentUser, Integer year, Integer month) {

        System.out.println("ywh-----cancelAudit");
        this.checkCheckOut(accountSetsId, year, month);
        LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
        qw.eq(Voucher::getAccountSetsId, accountSetsId);
        qw.eq(Voucher::getVoucherYear, year);
        qw.eq(Voucher::getVoucherMonth, month);
        qw.in(Voucher::getId, Arrays.asList(checked));
        qw.isNotNull(Voucher::getAuditMemberId);
        baseMapper.updateAudit(qw);

    }

    /**
     * 批量导入凭证
     *
     * @param voucherList
     * @return
     */
    @Override
    @Transactional
    public Date importVoucher(List<Voucher> voucherList, AccountSets accountSets) {
        System.out.println("ywh-----importVoucher");
        List<Date> voucherDateList = new ArrayList<>();
        for (Voucher voucher : voucherList) {
            this.save(voucher, accountSets, true);
            voucherDateList.add(DateUtil.getMonthEnd(voucher.getVoucherDate()));
        }

        List<Date> collect = voucherDateList.stream().distinct().sorted().collect(Collectors.toList());
        collect.forEach(date -> {
            LambdaQueryWrapper<Checkout> cqw = Wrappers.lambdaQuery();
            Calendar instance = Calendar.getInstance();
            instance.setTime(date);
            cqw.eq(Checkout::getAccountSetsId, accountSets.getId());
            cqw.eq(Checkout::getCheckYear, instance.get(Calendar.YEAR));
            cqw.eq(Checkout::getCheckMonth, instance.get(Calendar.MONTH) + 1);
            if (this.checkoutMapper.selectCount(cqw) == 0) {
                Checkout checkout = new Checkout();
                checkout.setAccountSetsId(accountSets.getId());
                checkout.setCheckYear(instance.get(Calendar.YEAR));
                checkout.setCheckMonth(instance.get(Calendar.MONTH) + 1);
                this.checkoutMapper.insert(checkout);
            }
        });

        Date date = this.baseMapper.selectMaxVoucherDate(accountSets.getId());
        accountSets.setCurrentAccountDate(DateUtil.getMonthEndWithTime(date, false));
        this.accountSetsMapper.updateById(accountSets);
        return date;
    }

    private boolean save(Voucher entity, AccountSets accountSets, boolean imports) {
        System.out.println("ywh-----save");
        this.setYearAndMonth(entity);
        if(!this.checkCode(entity)){
            return false;
        }
        boolean rs = super.save(entity);

        double debitAmount = 0d;
        double creditAmount = 0d;
        if (rs) {
            for (VoucherDetails vd : entity.getDetails()) {
                vd.setVoucherId(entity.getId());
                vd.setAccountSetsId(entity.getAccountSetsId());
                vd.setCarryForward(entity.getCarryForward());
                if (vd.getDebitAmount() != null) {
                    debitAmount += vd.getDebitAmount();
                }
                if (vd.getCreditAmount() != null) {
                    creditAmount += vd.getCreditAmount();
                }
            }

            System.out.println("凭证明细录入");
            System.out.println(entity.getDetails());
            detailsMapper.batchInsert(entity.getDetails());
            System.out.println("凭证明细录入完成");
            //存储辅助项目
            for (VoucherDetails voucherDetails : entity.getDetails()) {
                voucherDetails.setSummary(StringUtils.trim(voucherDetails.getSummary()));
                voucherDetails.setSubjectCode(StringUtils.trim(voucherDetails.getSubjectCode()));
                int size;
                if ((size = voucherDetails.getAuxiliary().size()) > 0) {
                    List<VoucherDetailsAuxiliary> vdas = new ArrayList<>(size);
                    voucherDetails.getAuxiliary().forEach(acd -> {
                        VoucherDetailsAuxiliary vda = new VoucherDetailsAuxiliary();
                        vda.setVoucherDetailsId(voucherDetails.getId());
                        vda.setAccountingCategoryId(acd.getAccountingCategoryId());
                        vda.setAccountingCategoryDetailsId(acd.getId());
                        vdas.add(vda);
                    });

                    System.out.println("辅助核算录入");
                    System.out.println(vdas);
                    voucherDetailsAuxiliaryMapper.batchInsert(vdas);
                    System.out.println("辅助核算录入完成");
                }
            }

            //更新总和
            entity.setCreditAmount(creditAmount);
            entity.setDebitAmount(debitAmount);
            System.out.println("更新总和");
            baseMapper.updateById(entity);
            System.out.println("更新总和完成");
            if (!imports) {
                // 如果是非当前期间切，当前账套时间在凭证时间之前，需要更改默认期间
                DateFormat df = new SimpleDateFormat("yyyyMM");
                if (!df.format(accountSets.getCurrentAccountDate()).equals(df.format(entity.getVoucherDate())) &&
                        accountSets.getCurrentAccountDate().before(entity.getVoucherDate())
                ) {
                    LambdaQueryWrapper<Checkout> cqw = Wrappers.lambdaQuery();
                    cqw.eq(Checkout::getAccountSetsId, entity.getAccountSetsId());
                    cqw.eq(Checkout::getCheckYear, entity.getVoucherYear());
                    cqw.eq(Checkout::getCheckMonth, entity.getVoucherMonth());
                    if (this.checkoutMapper.selectCount(cqw) == 0) {
                        Checkout checkout = new Checkout();
                        checkout.setAccountSetsId(entity.getAccountSetsId());
                        checkout.setCheckYear(entity.getVoucherYear());
                        checkout.setCheckMonth(entity.getVoucherMonth());
                        checkout.setCheckDate(entity.getVoucherDate());

                        System.out.println("this.checkoutMapper.insert(checkout);");
                        this.checkoutMapper.insert(checkout);

                        System.out.println("this.checkoutMapper.insert(checkout);完成");
                        //更新当前账套的当前期间
                        accountSets.setCurrentAccountDate(checkout.getCheckDate());
                        this.accountSetsMapper.updateById(accountSets);
                    }
                }
            }

        }

        return rs;
    }

    @Override
    @Transactional
    public boolean save(Voucher entity) {
        System.out.println("ywh-----最原始的save");
        return this.save(entity, this.accountSetsMapper.selectById(entity.getAccountSetsId()), false);
    }

    @Override
    @Transactional
    public boolean update(Voucher entity, Wrapper<Voucher> updateWrapper) {
        System.out.println("ywh-----update");
        this.setYearAndMonth(entity);
        this.checkCheckOut(entity.getAccountSetsId(), entity.getVoucherYear(), entity.getVoucherMonth());
        if (!this.checkCode(entity)){
            return false;
        }

        boolean rs = super.update(entity, updateWrapper);

        //删除原有明细
        LambdaQueryWrapper<VoucherDetails> qw = Wrappers.lambdaQuery();
        qw.eq(VoucherDetails::getVoucherId, entity.getId());
        detailsMapper.delete(qw);

        double debitAmount = 0d;
        double creditAmount = 0d;
        if (rs) {
            for (VoucherDetails vd : entity.getDetails()) {
                vd.setVoucherId(entity.getId());
                vd.setAccountSetsId(entity.getAccountSetsId());
                vd.setCarryForward(entity.getCarryForward());
                if (vd.getDebitAmount() != null) {
                    debitAmount += vd.getDebitAmount();
                }
                if (vd.getCreditAmount() != null) {
                    creditAmount += vd.getCreditAmount();
                }
            }

            detailsMapper.batchInsert(entity.getDetails());

            //存储辅助项目
            for (VoucherDetails voucherDetails : entity.getDetails()) {
                voucherDetails.setSummary(StringUtils.trim(voucherDetails.getSummary()));
                voucherDetails.setSubjectCode(StringUtils.trim(voucherDetails.getSubjectCode()));
                int size;
                if ((size = voucherDetails.getAuxiliary().size()) > 0) {
                    List<VoucherDetailsAuxiliary> vdas = new ArrayList<>(size);
                    voucherDetails.getAuxiliary().forEach(acd -> {
                        VoucherDetailsAuxiliary vda = new VoucherDetailsAuxiliary();
                        vda.setVoucherDetailsId(voucherDetails.getId());
                        vda.setAccountingCategoryId(acd.getAccountingCategoryId());
                        vda.setAccountingCategoryDetailsId(acd.getId());
                        vdas.add(vda);
                    });

                    voucherDetailsAuxiliaryMapper.batchInsert(vdas);
                }
            }

            //更新总和
            entity.setCreditAmount(creditAmount);
            entity.setDebitAmount(debitAmount);
            baseMapper.updateById(entity);
        }


        return rs;
    }

    @Override
    public Voucher getOne(Wrapper<Voucher> queryWrapper) {
        List<Voucher> vouchers = baseMapper.selectVoucher(queryWrapper);
        if (vouchers.size() > 0) {
            return vouchers.get(0);
        }
        return null;
    }

    @Override
    @Transactional
    public boolean remove(Wrapper<Voucher> wrapper) {
        Voucher voucher = baseMapper.selectOne(wrapper);
        this.checkCheckOut(voucher.getAccountSetsId(), voucher.getVoucherYear(), voucher.getVoucherMonth());

        LambdaQueryWrapper<VoucherDetails> qw = Wrappers.lambdaQuery();
        qw.eq(VoucherDetails::getVoucherId, voucher.getId());
        detailsMapper.delete(qw);

        return baseMapper.delete(wrapper) > 0;
    }

    private Boolean checkCode(Voucher entity) {
        LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
        qw.eq(Voucher::getCode, entity.getCode());
        qw.eq(Voucher::getWord, entity.getWord());
        qw.eq(Voucher::getVoucherYear, entity.getVoucherYear());
        qw.eq(Voucher::getVoucherMonth, entity.getVoucherMonth());
        qw.eq(Voucher::getAccountSetsId, entity.getAccountSetsId());

        if (entity.getId() != null) {
            qw.ne(Voucher::getId, entity.getId());
        }

        if (this.count(qw) > 0) {
//            return "亲,凭证字号[" + entity.getWord() + "-" + entity.getCode() + "]已经存在！";
            return false;
        }else {
            return true;
        }
    }

    private void checkCheckOut(Integer accountSetsId, Integer year, Integer month) {
        LambdaQueryWrapper<Checkout> cqw = Wrappers.lambdaQuery();
        cqw.eq(Checkout::getAccountSetsId, accountSetsId);
        cqw.eq(Checkout::getCheckYear, year);
        cqw.eq(Checkout::getCheckMonth, month);
        cqw.eq(Checkout::getStatus, 2);

        if (checkoutMapper.selectCount(cqw) > 0) {
            throw new ServiceException("亲,期间已结账，不允许操作凭证！");
        }
    }

    private void setYearAndMonth(Voucher entity) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(entity.getVoucherDate());
        entity.setVoucherYear(calendar.get(Calendar.YEAR));
        entity.setVoucherMonth(calendar.get(Calendar.MONDAY) + 1);

        AccountSets accountSets = this.accountSetsMapper.selectById(entity.getAccountSetsId());
        Date d = DateUtil.getMonthEnd(accountSets.getEnableDate());
        Date d2 = DateUtil.getMonthEnd(entity.getVoucherDate());
        if (d.after(d2)) {
            throw new ServiceException("亲,日期不能小于账套启用日期：" + DateFormatUtils.format(d, "yyyy-MM-dd"));
        }
    }

    /**
     * 汇总和明细账
     *
     * @param accountSetsId
     * @param subjectId
     * @param accountDate
     * @param subjectCode
     * @param details
     * @return
     */
    public List<VoucherDetailVo> summary(Integer accountSetsId, Integer subjectId, Date accountDate, String subjectCode, Boolean showNumPrice, boolean details) {
        Subject subject = subjectMapper.selectById(subjectId);
        LambdaQueryWrapper<Subject> sqw = Wrappers.lambdaQuery();
        sqw.likeRight(Subject::getCode, subjectCode);
        sqw.eq(Subject::getAccountSetsId, accountSetsId);
        List<Subject> subjects = subjectMapper.selectList(sqw);
        List<Integer> sids = subjects.stream().map(Subject::getId).collect(Collectors.toList());

        List<VoucherDetailVo> initialBalance = baseMapper.selectAccountBookInitialBalance(accountSetsId, sids, DateUtil.getMonthBegin(accountDate));
        System.out.println("initialBalance----"+initialBalance);
        System.out.println(initialBalance.size());

        VoucherDetailVo init;
        //没有期初
        if (initialBalance.get(0).getCreditAmount()==null&&initialBalance.get(0).getDebitAmount()==null) {
            init = new VoucherDetailVo();
            init.setVoucherDate(DateUtil.getMonthBegin(accountDate));
            init.setSummary("期初余额");
            init.setBalanceDirection("平");
            init.setSubjectName(subject.getCode() + "-" + subject.getName());
            init.setBalance(0d);
            initialBalance.set(0,init);
        } else {
            init = initialBalance.get(0);
            init.setVoucherDate(DateUtil.getMonthBegin(accountDate));
        }

        List<VoucherDetailVo> statistical = baseMapper.selectAccountBookStatistical(accountSetsId, subjectId, sids, DateUtil.getMonthEnd(accountDate));

        //科目明细
        if (details) {
            VoucherDetailVo pre = init;
            //初始数量余额
            pre.setNumBalance(pre.getNum());

            List<VoucherDetailVo> list = baseMapper.selectAccountBookDetails(accountSetsId, sids, accountDate);
            System.out.println(list);
            //计算余额
            for (int i = 0; i < list.size(); i++) {
                if (i > 0) {
                    pre = list.get(i - 1);
                }
                VoucherDetailVo vo = list.get(i);
                switch (vo.getBalanceDirection()) {
                    case "借":
                        if (vo.getDebitAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        } else if (vo.getCreditAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        }

                        if (vo.getNum() != null) {
                            vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + vo.getNum());
                        } else {
                            vo.setNumBalance(pre.getNumBalance());
                        }
                        break;
                    case "贷":
                        if (vo.getDebitAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        } else if (vo.getCreditAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        }
                        if (vo.getNum() != null) {
                            vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - vo.getNum());
                        } else {
                            vo.setNumBalance(pre.getNumBalance());
                        }
                        break;
                }
            }

            initialBalance.addAll(list);
        }

        //设置汇总余额
        Double balance = null;
        for (VoucherDetailVo vo : statistical) {
            double he = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
            switch (vo.getBalanceDirection()) {
                case "借":
                    vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) + he);
                    break;
                case "贷":
                    vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) - he);
                    break;
            }
            if (vo.getSummary().equals("本期合计")) {
                balance = vo.getBalance();
            } else {
                vo.setBalance(DoubleValueUtil.getNotNullVal(balance, init.getBalance()));
            }
            vo.setNumBalance(vo.getNum());
            vo.setVoucherDate(DateUtil.getMonthEnd(accountDate));
        }

        initialBalance.addAll(statistical);

        return initialBalance;
    }
    public List<VoucherDetailVo> summaryAccountBook(AccountBookVo aVo,Integer accountSetsId, Integer subjectId, List<String> time, String subjectCode, Boolean showNumPrice,Integer currencyId) {
        if (currencyId == -1){
            currencyId = null;
        }
        Date date1 = new Date();
        try {
            date1 = new SimpleDateFormat("yyyy-MM").parse(time.get(0));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Subject subject = subjectMapper.selectById(subjectId);
        LambdaQueryWrapper<Subject> sqw = Wrappers.lambdaQuery();
        sqw.likeRight(Subject::getCode, subjectCode);
        sqw.eq(Subject::getAccountSetsId, accountSetsId);
        List<Subject> subjects = subjectMapper.selectList(sqw);
        System.out.println("wuwuwuwuuwuwuwu~~~~~~"+subjects);
        List<Integer> sids = subjects.stream().map(Subject::getId).collect(Collectors.toList());
        List<VoucherDetailVo> initialBalance = baseMapper.selectAccountBookInitialBalanceSup(accountSetsId, sids, DateUtil.getMonthBegin(date1),subjectCode,currencyId);


        System.out.println("initialBalance----"+initialBalance);
        System.out.println(initialBalance.size());
        for (int i = 0; i < initialBalance.size(); i++) {
            initialBalance.get(i).setSubjectName(aVo.getSubjectCode() + "-" + aVo.getSubjectName());
        }
        VoucherDetailVo init;
        //没有期初
        if ((initialBalance.get(0).getDebitAmount()==null||initialBalance.get(0).getDebitAmount()==0.0)
                &&(initialBalance.get(0).getCreditAmount()==null||initialBalance.get(0).getCreditAmount()==0.0)
                &&(initialBalance.get(0).getBalance()==null||initialBalance.get(0).getBalance()==0.0)) {
            init = new VoucherDetailVo();
            init.setVoucherDate(DateUtil.getMonthBegin(date1));
            init.setSummary("期初余额");
            init.setBalanceDirection("平");
            if (initialBalance.get(0).getNum()!=null && !initialBalance.get(0).getNum().equals(0.0)){
                init.setNum(initialBalance.get(0).getNum());
            }
            init.setSubjectName(aVo.getSubjectCode() + "-" + aVo.getSubjectName());
            init.setBalance(0d);
            initialBalance.set(0,init);
        } else {
            init = initialBalance.get(0);
            init.setVoucherDate(DateUtil.getMonthBegin(date1));
        }
        System.out.println(initialBalance);
        Double realInit = DoubleValueUtil.getNotNullVal(initialBalance.get(0).getBalance());
        Double realInitNum = DoubleValueUtil.getNotNullVal(initialBalance.get(0).getNum());
        Double hZ = 0d;
        Double hzNum = 0d;
        String balanceDirection = "";
        for (int j = 0; j < time.size(); j++) {
            Date date2 = new Date();
            try {
                date2 = new SimpleDateFormat("yyyy-MM").parse(time.get(j));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            List<VoucherDetailVo> statistical;
            if (currencyId == null){
                statistical = baseMapper.selectAccountBookStatistical(accountSetsId, subjectId, sids,DateUtil.getMonthEnd(date2));
            }else {
                statistical = baseMapper.selectAccountBookStatisticalSup(accountSetsId, subjectId, sids,DateUtil.getMonthEnd(date2));
            }

            System.out.println("statistical----"+statistical);



            if (statistical.size()==1 && statistical.get(0).getSummary().equals("本年累计")
                    && ((statistical.get(0).getDebitAmount()!=null && !statistical.get(0).getDebitAmount().equals(0.0))
                    || (statistical.get(0).getCreditAmount()!=null && !statistical.get(0).getCreditAmount().equals(0.0)))){
                VoucherDetailVo stat1 = new VoucherDetailVo();
                stat1.setSummary("本期合计");
                stat1.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat1.setBalanceDirection(balanceDirection);
                }else {
                    stat1.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }
                stat1.setVoucherDate(DateUtil.getMonthEnd(date2));
                statistical.add(0,stat1);
            }

            else if (statistical.size()!=2){
                VoucherDetailVo stat1 = new VoucherDetailVo();
                VoucherDetailVo stat2 = new VoucherDetailVo();
                stat1.setSummary("本期合计");
                stat1.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat1.setBalanceDirection(balanceDirection);
                }else {
                    stat1.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }
                stat1.setVoucherDate(DateUtil.getMonthEnd(date2));

                stat2.setSummary("本年累计");
                stat2.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat2.setBalanceDirection(balanceDirection);
                }else {
                    stat2.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }

                stat2.setVoucherDate(DateUtil.getMonthEnd(date2));

                if (statistical.size()==0){
                    statistical.add(stat1);
                    statistical.add(stat2);
                }
                if (statistical.size()==1){
                    statistical.set(0,stat1);
                    statistical.add(stat2);
                }
                System.out.println("改后的statistical"+statistical);
            }
            balanceDirection = statistical.get(0).getBalanceDirection();
            //科目明细
            if (showNumPrice) {

                VoucherDetailVo pre = init;
                pre.setNumBalance(pre.getNum());
                System.out.println(pre.getNum()+"=-=-===============---------");
                //初始数量余额
                if(j>0){
                    System.out.println("hz前："+initialBalance);
                    System.out.println("ZOUZHELI");
                    System.out.println("ZOUZHELI"+hZ);
                    pre.setBalance(hZ);
                    pre.setNumBalance(hzNum);
                    System.out.println("hz后："+initialBalance);
                }


                List<VoucherDetailVo> list = baseMapper.selectAccountBookDetailsSip(accountSetsId, sids, date2,currencyId);
                System.out.println(list);
                if (list.size()!=0){
                    for (int i = 0; i < list.size(); i++) {
                        list.get(i).setBalanceDirection(baseMapper.selectBalanceDirection(subjectCode,accountSetsId));
                    }
                }
                //计算余额
                for (int i = 0; i < list.size(); i++) {
                    if (i > 0) {
                        pre = list.get(i - 1);
                    }
                    VoucherDetailVo vo = list.get(i);
                    switch (baseMapper.selectBalanceDirection(subjectCode,accountSetsId)) {
                        case "借":
                            if (vo.getDebitAmount() != null && !vo.getDebitAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance())+DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()));
                            } else if (vo.getCreditAmount() != null && !vo.getCreditAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance())-DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum()));
                            }

//                            if (vo.getNum() != null) {
//                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + vo.getNum());
//                            } else {
//                                vo.setNumBalance(pre.getNumBalance());
//                            }
                            break;
                        case "贷":
                            if (vo.getDebitAmount() != null && !vo.getDebitAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance())-DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()));
                            } else if (vo.getCreditAmount() != null && !vo.getCreditAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance())+DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum()));
                            }
//                            if (vo.getNum() != null) {
//                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - vo.getNum());
//                            } else {
//                                vo.setNumBalance(pre.getNumBalance());
//                            }
                            break;
                    }
                }
//                System.out.println("1加前："+initialBalance);
                initialBalance.addAll(list);
//                System.out.println("1加hou："+initialBalance);
            }

            //设置汇总余额
            Double balance = null;
            Double balanceNum = null;
            for (VoucherDetailVo vo : statistical) {
                System.out.println("v0---------------------------"+vo);
                double he = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                double heNum = DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()) - DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum());
                System.out.println(vo.getSummary()+"发生额"+he);
                System.out.println(vo.getSummary()+"发生额"+heNum);
                switch (baseMapper.selectBalanceDirection(subjectCode,accountSetsId)) {
                    case "借":
                        vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) + he);
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(init.getNumBalance()) + heNum);
                        break;
                    case "贷":
                        vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) - he);
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(init.getNumBalance()) - heNum);
                        break;
                }
                System.out.println("余额"+vo.getBalance());
                if (vo.getSummary().equals("本期合计")) {
                    balance = vo.getBalance();
                    balanceNum = vo.getNumBalance();
                } else {
                    vo.setBalance(DoubleValueUtil.getNotNullVal(balance, init.getBalance()));
                    vo.setNumBalance(DoubleValueUtil.getNotNullVal(balanceNum, init.getNumBalance()));
                }
//                vo.setNumBalance(vo.getNum()+);
                vo.setVoucherDate(DateUtil.getMonthEnd(date2));
            }
            if (statistical.get(0).getBalance()!=null){
                hZ = statistical.get(0).getBalance();
            }else {
                hZ = initialBalance.get(0).getBalance();
            }

            if (statistical.get(0).getNumBalance()!=null){
                hzNum = statistical.get(0).getNumBalance();
            }else {
                hzNum = initialBalance.get(0).getNumBalance();
            }
            System.out.println("2加前："+initialBalance);
            initialBalance.addAll(statistical);
            System.out.println("2加后："+initialBalance);
        }
        if (initialBalance.get(0).getBalanceDirection().equals("平")){
            initialBalance.get(0).setBalance(0d);
            initialBalance.get(0).setNumBalance(DoubleValueUtil.getNotNullVal(realInitNum));
        }else {
            initialBalance.get(0).setBalance(realInit);
            initialBalance.get(0).setNumBalance(DoubleValueUtil.getNotNullVal(realInitNum));
        }
        for (int i = 0; i <initialBalance.size() ; i++) {
            if (initialBalance.get(i).getBalance()==null||initialBalance.get(i).getBalance()==0.0){
                initialBalance.get(i).setBalanceDirection("平");
            }else {
                if (subject.getBalanceDirection().equals("借")){
                    if (initialBalance.get(i).getBalance()>0){
                        initialBalance.get(i).setBalanceDirection("借");
                    }else {
                        initialBalance.get(i).setBalanceDirection("贷");
                    }
                }
                if (subject.getBalanceDirection().equals("贷")){
                    if (initialBalance.get(i).getBalance()>0){
                        initialBalance.get(i).setBalanceDirection("贷");
                    }else {
                        initialBalance.get(i).setBalanceDirection("借");
                    }
                }
            }
        }
        VoucherDetailVo yearAmount = baseMapper.selectyearAmountByOne(accountSetsId,subjectCode,currencyId);
        for (int i = 0; i <initialBalance.size() ; i++) {
            if (initialBalance.get(i).getCumulativeCreditNum()!=null && initialBalance.get(i).getCumulativeCreditNum().equals(0.0)){
                initialBalance.get(i).setCumulativeCreditNum(null);
            }
            if (initialBalance.get(i).getCumulativeCreditNum()!=null && initialBalance.get(i).getCumulativeDebitNum().equals(0.0)){
                initialBalance.get(i).setCumulativeDebitNum(null);
            }
            if (initialBalance.get(i).getSummary().equals("本年累计")){
                initialBalance.get(i).setCreditAmount(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getCreditAmount())+DoubleValueUtil.getNotNullVal(yearAmount.getCumulativeCredit()));
                initialBalance.get(i).setDebitAmount(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getDebitAmount())+DoubleValueUtil.getNotNullVal(yearAmount.getCumulativeDebit()));
                initialBalance.get(i).setPrice(null);
            }
            if (initialBalance.get(i).getSummary().equals("本期合计")){
                initialBalance.get(i).setPrice(null);
            }
            if (initialBalance.get(i).getBalance()<0){
                System.out.println(initialBalance.get(i).getBalanceDirection()+"initialBalance.get(i).getBalanceDirection()");
//                if (initialBalance.get(i).getBalanceDirection().equals("借")){
//                    initialBalance.get(i).setBalanceDirection("贷");
//                }else {
//                    initialBalance.get(i).setBalanceDirection("借");
//                }
                initialBalance.get(i).setBalance(0-initialBalance.get(i).getBalance());
            }
        }
        return initialBalance;
    }

    public List<VoucherDetailCurrencyVo> summaryCurrency(AccountBookVo aVo,Integer accountSetsId, Integer subjectId, List<String> time, String subjectCode, Boolean showNumPrice,Integer currencyId) {
        Date date1 = new Date();
        try {
            date1 = new SimpleDateFormat("yyyy-MM").parse(time.get(0));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Subject subject = subjectMapper.selectById(subjectId);
        LambdaQueryWrapper<Subject> sqw = Wrappers.lambdaQuery();
        sqw.likeRight(Subject::getCode, subjectCode);
        sqw.eq(Subject::getAccountSetsId, accountSetsId);
        List<Subject> subjects = subjectMapper.selectList(sqw);
        System.out.println("wuwuwuwuuwuwuwu~~~~~~"+subjects);
        List<Integer> sids = subjects.stream().map(Subject::getId).collect(Collectors.toList());


        List<VoucherDetailCurrencyVo> initialBalance = baseMapper.selectAccountBookInitialBalance1(accountSetsId, sids, DateUtil.getMonthBegin(date1),subjectCode,currencyId);
        Currency currency = baseMapper.selectCurrency(currencyId);
        System.out.println("initialBalance----"+initialBalance);
        System.out.println(initialBalance.size());
        for (int i = 0; i < initialBalance.size(); i++) {
            initialBalance.get(i).setSubjectName(aVo.getSubjectCode() + "-" + aVo.getSubjectName());
        }
        initialBalance.get(0).setCurrencyId(currencyId);
        initialBalance.get(0).setCurrencyName(currency.getCode());
//        initialBalance.get(0).setExchangeRate(currency.getExchangeRate());
        VoucherDetailCurrencyVo init;
        //没有期初
        if ((initialBalance.get(0).getDebitAmount()==null||initialBalance.get(0).getDebitAmount()==0.0)
                &&(initialBalance.get(0).getCreditAmount()==null||initialBalance.get(0).getCreditAmount()==0.0)
                &&(initialBalance.get(0).getBalance()==null||initialBalance.get(0).getBalance()==0.0)) {
            init = new VoucherDetailCurrencyVo();
            init.setVoucherDate(DateUtil.getMonthBegin(date1));
            init.setSummary("期初余额");
            init.setBalanceDirection("平");
            init.setSubjectName(aVo.getSubjectCode() + "-" + aVo.getSubjectName());
            init.setOriginalAmount(0d);
            if (initialBalance.get(0).getNum()!=null && !initialBalance.get(0).getNum().equals(0.0)){
                init.setNum(initialBalance.get(0).getNum());
            }
            init.setBalance(0d);
            init.setCurrencyId(currencyId);
            init.setCurrencyName(currency.getCode());
//            init.setExchangeRate(currency.getExchangeRate());
            initialBalance.set(0,init);
        } else {
            init = initialBalance.get(0);
            init.setVoucherDate(DateUtil.getMonthBegin(date1));
        }
        System.out.println(initialBalance);
        Double realInit = DoubleValueUtil.getNotNullVal(initialBalance.get(0).getBalance());
        Double realCurrencyAmount = DoubleValueUtil.getNotNullVal(initialBalance.get(0).getOriginalAmount());
        Double realInitNum = DoubleValueUtil.getNotNullVal(initialBalance.get(0).getNum());
        Double hZ = 0d;
        Double hzNum = 0d;
        Double hzCurrency = 0d;
        String balanceDirection = "";
        for (int j = 0; j < time.size(); j++) {
            Date date2 = new Date();
            try {
                date2 = new SimpleDateFormat("yyyy-MM").parse(time.get(j));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            List<VoucherDetailCurrencyVo> statistical = baseMapper.selectAccountBookStatisticalCurrency(accountSetsId, subjectId, sids, DateUtil.getMonthEnd(date2),currencyId);

            System.out.println("statistical----"+statistical);

            if (statistical.size()==1 && statistical.get(0).getSummary().equals("本年累计")
                    && ((statistical.get(0).getDebitAmount()!=null && !statistical.get(0).getDebitAmount().equals(0.0))
                    || (statistical.get(0).getCreditAmount()!=null && !statistical.get(0).getCreditAmount().equals(0.0)))){
                VoucherDetailCurrencyVo stat1 = new VoucherDetailCurrencyVo();
                VoucherDetailCurrencyVo stat2 = new VoucherDetailCurrencyVo();
                stat1.setSummary("本期合计");
                stat1.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat1.setBalanceDirection(balanceDirection);
                }else {
                    stat1.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }
                stat1.setVoucherDate(DateUtil.getMonthEnd(date2));
                statistical.add(0,stat1);
            }
            else if (statistical.size()!=2){
                VoucherDetailCurrencyVo stat1 = new VoucherDetailCurrencyVo();
                VoucherDetailCurrencyVo stat2 = new VoucherDetailCurrencyVo();
                stat1.setSummary("本期合计");
                stat1.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat1.setBalanceDirection(balanceDirection);
                }else {
                    stat1.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }
                stat1.setVoucherDate(DateUtil.getMonthEnd(date2));

                stat2.setSummary("本年累计");
                stat2.setSubjectName(subject.getCode() + "-" + subject.getName());
                if (j>0){
                    stat2.setBalanceDirection(balanceDirection);
                }else {
                    stat2.setBalanceDirection(initialBalance.get(0).getBalanceDirection());
                }

                stat2.setVoucherDate(DateUtil.getMonthEnd(date2));

                if (statistical.size()==0){
                    statistical.add(stat1);
                    statistical.add(stat2);
                }
                if (statistical.size()==1){
                    statistical.set(0,stat1);
                    statistical.add(stat2);
                }
                System.out.println("改后的statistical"+statistical);
            }
            balanceDirection = statistical.get(0).getBalanceDirection();
            //科目明细
            if (showNumPrice) {

                VoucherDetailCurrencyVo pre = init;
                pre.setNumBalance(pre.getNum());
                //初始数量余额
                if(j>0){
                    System.out.println("hz前："+initialBalance);
                    System.out.println("ZOUZHELI");
                    System.out.println("ZOUZHELI"+hZ);
                    pre.setOriginalAmount(hzCurrency);
                    pre.setBalance(hZ);
                    pre.setNumBalance(hzNum);
                    System.out.println("hz后："+initialBalance);
                }


                List<VoucherDetailCurrencyVo> list = baseMapper.selectCurrAccountBookDetails(accountSetsId, sids, date2 ,currencyId);
                System.out.println(list);
                if (list.size()!=0){
                    for (int i = 0; i < list.size(); i++) {
                        list.get(i).setBalanceDirection(baseMapper.selectBalanceDirection(subjectCode,accountSetsId));
                    }
                }
                //计算余额
                for (int i = 0; i < list.size(); i++) {
                    if (i > 0) {
                        pre = list.get(i - 1);
                    }
                    VoucherDetailCurrencyVo vo = list.get(i);
                    switch (baseMapper.selectBalanceDirection(subjectCode,accountSetsId)) {
                        case "借":
                            if (vo.getDebitAmount() != null && !vo.getDebitAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                                vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(pre.getOriginalAmount()) + DoubleValueUtil.getNotNullVal(vo.getCurrencyDebit()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()));

                            } else if (vo.getCreditAmount() != null && !vo.getCreditAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                                vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(pre.getOriginalAmount()) - DoubleValueUtil.getNotNullVal(vo.getCurrencyCredit()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum()));

                            }

//                            if (vo.getNum() != null) {
//                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + vo.getNum());
//                            } else {
//                                vo.setNumBalance(pre.getNumBalance());
//                            }
                            break;
                        case "贷":
                            if (vo.getDebitAmount() != null && !vo.getDebitAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                                vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(pre.getOriginalAmount()) - DoubleValueUtil.getNotNullVal(vo.getCurrencyDebit()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()));
                            } else if (vo.getCreditAmount() != null && !vo.getCreditAmount().equals(0.0)) {
                                vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                                vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(pre.getOriginalAmount()) + DoubleValueUtil.getNotNullVal(vo.getCurrencyCredit()));
                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum()));

                            }
//                            if (vo.getNum() != null) {
//                                vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - vo.getNum());
//                            } else {
//                                vo.setNumBalance(pre.getNumBalance());
//                            }
                            break;
                    }
                }
                System.out.println("1加前："+initialBalance);
                initialBalance.addAll(list);
                System.out.println("1加hou："+initialBalance);
            }

            //设置汇总余额
            Double balance = null;
            Double balanceCurrcy = null;
            for (VoucherDetailCurrencyVo vo : statistical) {
                double he = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
                double heCurrency = DoubleValueUtil.getNotNullVal(vo.getCurrencyDebit()) - DoubleValueUtil.getNotNullVal(vo.getCurrencyCredit());
                double heNum = DoubleValueUtil.getNotNullVal(vo.getCumulativeDebitNum()) - DoubleValueUtil.getNotNullVal(vo.getCumulativeCreditNum());
                switch (baseMapper.selectBalanceDirection(subjectCode,accountSetsId)) {
                    case "借":
                        vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) + he);
                        vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(init.getOriginalAmount()) + heCurrency);
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(init.getNumBalance()) + heNum);
                        break;
                    case "贷":
                        vo.setBalance(DoubleValueUtil.getNotNullVal(init.getBalance()) - he);
                        vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(init.getOriginalAmount()) - heCurrency);
                        vo.setNumBalance(DoubleValueUtil.getNotNullVal(init.getNumBalance()) - heNum);
                        break;
                }
                if (vo.getSummary().equals("本期合计")) {
                    balance = vo.getBalance();
                    balanceCurrcy = vo.getOriginalAmount();
                } else {
                    vo.setBalance(DoubleValueUtil.getNotNullVal(balance, init.getBalance()));
                    vo.setOriginalAmount(DoubleValueUtil.getNotNullVal(balanceCurrcy, init.getOriginalAmount()));
                }

                vo.setVoucherDate(DateUtil.getMonthEnd(date2));
            }
            if (statistical.get(0).getBalance()!=null){
                hZ = statistical.get(0).getBalance();
            }else {
                hZ = initialBalance.get(0).getBalance();
            }
            if (statistical.get(0).getNumBalance()!=null){
                hzNum = statistical.get(0).getNumBalance();
            }else {
                hzNum = initialBalance.get(0).getNumBalance();
            }
            if (statistical.get(0).getOriginalAmount()!=null){
                hzCurrency = statistical.get(0).getOriginalAmount();
            }else {
                hzCurrency = initialBalance.get(0).getOriginalAmount();
            }
            System.out.println("2加前："+initialBalance);
            initialBalance.addAll(statistical);
            System.out.println("2加后："+initialBalance);
        }
        initialBalance.get(0).setNumBalance(realInitNum);
        if (initialBalance.get(0).getBalanceDirection().equals("平")){
            initialBalance.get(0).setBalance(0d);
            initialBalance.get(0).setOriginalAmount(0d);
        }else {
            initialBalance.get(0).setBalance(realInit);
            initialBalance.get(0).setOriginalAmount(realCurrencyAmount);
        }
        for (int i = 0; i <initialBalance.size() ; i++) {
            if (initialBalance.get(i).getBalance()==null||initialBalance.get(i).getBalance()==0.0){
                initialBalance.get(i).setBalanceDirection("平");
            }else {
                if (subject.getBalanceDirection().equals("借")){
                    if (initialBalance.get(i).getBalance()>0){
                        initialBalance.get(i).setBalanceDirection("借");
                    }else {
                        initialBalance.get(i).setBalanceDirection("贷");
                    }
                }
                if (subject.getBalanceDirection().equals("贷")){
                    if (initialBalance.get(i).getBalance()>0){
                        initialBalance.get(i).setBalanceDirection("贷");
                    }else {
                        initialBalance.get(i).setBalanceDirection("借");
                    }
                }
            }
        }
        VoucherDetailVo yearAmount = baseMapper.selectyearAmountByOneByCurrency(accountSetsId,subjectCode,currencyId);
        for (int i = 0; i <initialBalance.size() ; i++) {
            if (initialBalance.get(i).getCumulativeCreditNum()!=null && initialBalance.get(i).getCumulativeCreditNum().equals(0.0)){
                initialBalance.get(i).setCumulativeCreditNum(null);
            }
            if (initialBalance.get(i).getCumulativeCreditNum()!=null && initialBalance.get(i).getCumulativeDebitNum().equals(0.0)){
                initialBalance.get(i).setCumulativeDebitNum(null);
            }
            if (initialBalance.get(i).getSummary().equals("本年累计")){
                System.out.println("aaaaaaaaaaaaaaaaaaaaaaaa"+initialBalance.get(i));
                System.out.println("bbbbbbbbbbbbbbbbbbbbbbbbbb"+yearAmount);
                initialBalance.get(i).setCreditAmount(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getCreditAmount())+DoubleValueUtil.getNotNullVal(yearAmount.getCumulativeCredit()));
                initialBalance.get(i).setDebitAmount(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getDebitAmount())+DoubleValueUtil.getNotNullVal(yearAmount.getCumulativeDebit()));
                initialBalance.get(i).setCurrencyCredit(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getCurrencyCredit())+DoubleValueUtil.getNotNullVal(yearAmount.getCurrencyCredit()));
                initialBalance.get(i).setCurrencyDebit(DoubleValueUtil.getNotNullVal(initialBalance.get(i).getCurrencyDebit())+DoubleValueUtil.getNotNullVal(yearAmount.getCurrencyDebit()));
                initialBalance.get(i).setPrice(null);
            }
            if (initialBalance.get(i).getSummary().equals("本期合计")){
//                initialBalance.get(i).setCurrencyName(null);
//                initialBalance.get(i).setExchangeRate(null);
                initialBalance.get(i).setPrice(null);
            }
            if (initialBalance.get(i).getBalance()<0){
                System.out.println(initialBalance.get(i).getBalanceDirection()+"initialBalance.get(i).getBalanceDirection()");
//                if (initialBalance.get(i).getBalanceDirection().equals("借")){
//                    initialBalance.get(i).setBalanceDirection("贷");
//                }else {
//                    initialBalance.get(i).setBalanceDirection("借");
//                }
                initialBalance.get(i).setBalance(0-initialBalance.get(i).getBalance());
            }
        }
        return initialBalance;
    }
    /**
     * 总账动态查询中的   汇总和明细账
     *
     * @param accountSetsId
     * @param subjectId
     * @param
     * @param subjectCode
     * @param details
     * @return
     */
    public List<VoucherDetailVo> summary1(Integer accountSetsId, Integer subjectId,String subjectCode,String sTime,String eTime, boolean details) throws ParseException {

        Subject subject = subjectMapper.selectById(subjectId);
        LambdaQueryWrapper<Subject> sqw = Wrappers.lambdaQuery();
        sqw.likeRight(Subject::getCode, subjectCode);
        //sqw.eq(Subject::getCode, subjectCode);
        sqw.eq(Subject::getAccountSetsId, accountSetsId);
        List<Subject> subjects = subjectMapper.selectList(sqw);
        List<Integer> sids = subjects.stream().map(Subject::getId).collect(Collectors.toList());

        //获取期初余额；
        // 开始日期为：账套的启动日期
        // 结束日期为：先拿到开始月份，获取上个月的最后一天
        Date lastMonthEndTime = cn.gson.financial.kernel.utils.DateUtil.getLastMonthEndTime(cn.gson.financial.kernel.utils.DateUtil.parseDate(sTime));
        List<VoucherDetailVo> initialBalance = baseMapper.selectAccountBookInitialBalanceByParam(accountSetsId, sids,cn.gson.financial.kernel.utils.DateUtil.formatDate(lastMonthEndTime));

        List<VoucherDetailVo> statistical = baseMapper.selectAccountBookStatisticalByParam(accountSetsId, subjectId, sids,sTime ,eTime);
        System.out.println("---------------start-------");
        statistical.forEach(System.out::println);
        System.out.println("---------------end-------");
        VoucherDetailVo init;
        //没有期初
        if (initialBalance.size() == 0) {
            init = new VoucherDetailVo();
            init.setVoucherDate(DateUtil.getMonthBegin(new SimpleDateFormat("yyyy-MM-dd").parse(sTime)));
            init.setSummary("期初余额");
            init.setBalanceDirection("平");
            init.setSubjectName(subject.getCode() + "-" + subject.getName());
            init.setBalance(0d);
            initialBalance.add(init);
        } else {
            initialBalance.forEach(voucherDetailVo -> {
                voucherDetailVo.setBalanceDirection(BaseUtil.checkDoubleIsNull(voucherDetailVo.getBalance()) == 0?"平":voucherDetailVo.getBalanceDirection());
            });
            init = initialBalance.get(0);
            init.setVoucherDate(DateUtil.getMonthBegin(new SimpleDateFormat("yyyy-MM-dd").parse(sTime)));
        }

        //科目明细
        if (details) {
            VoucherDetailVo pre = init;
            //初始数量余额
            pre.setNumBalance(pre.getNum());

            List<VoucherDetailVo> list = baseMapper.selectAccountBookDetailsByParam(accountSetsId, sids, sTime,eTime);
            //计算余额
            for (int i = 0; i < list.size(); i++) {
                if (i > 0) {
                    pre = list.get(i - 1);
                }
                VoucherDetailVo vo = list.get(i);
                switch (vo.getBalanceDirection()) {
                    case "借":
                        if (vo.getDebitAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        } else if (vo.getCreditAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        }

                        if (vo.getNum() != null) {
                            vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) + vo.getNum());
                        } else {
                            vo.setNumBalance(pre.getNumBalance());
                        }
                        break;
                    case "贷":
                        if (vo.getDebitAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) - DoubleValueUtil.getNotNullVal(vo.getDebitAmount()));
                        } else if (vo.getCreditAmount() != null) {
                            vo.setBalance(DoubleValueUtil.getNotNullVal(pre.getBalance()) + DoubleValueUtil.getNotNullVal(vo.getCreditAmount()));
                        }
                        if (vo.getNum() != null) {
                            vo.setNumBalance(DoubleValueUtil.getNotNullVal(pre.getNumBalance()) - vo.getNum());
                        } else {
                            vo.setNumBalance(pre.getNumBalance());
                        }
                        break;
                }
            }
            initialBalance.addAll(list);
        }

        //设置汇总余额
        Double balance = null;
        Double currencyBalance = null;
        for (VoucherDetailVo vo : statistical) {
//            if (vo.getSummary().equals("本期合计")){
//            }
            double he = DoubleValueUtil.getNotNullVal(vo.getDebitAmount()) - DoubleValueUtil.getNotNullVal(vo.getCreditAmount());
            double currencySum = DoubleValueUtil.getNotNullVal(vo.getCurrencyDebit()) - DoubleValueUtil.getNotNullVal(vo.getCurrencyCredit());
            switch (vo.getBalanceDirection()) {
                case "借":
                    Double balanceSum1  = DoubleValueUtil.getNotNullVal(init.getBalance()) + he;
                    if (BaseUtil.checkValueIsNull(init.getSubjectName()).equals("100203-招商银行7777")){
                        System.out.println("init="+init);
                    }
                    Double currencyBalanceSum1 = DoubleValueUtil.getNotNullVal(init.getCurrencyBalance()) + currencySum;
                    if (balanceSum1 < 0 && currencyBalanceSum1 <= 0){
                        vo.setBalance(-balanceSum1);
                        vo.setCurrencyBalance(-currencyBalanceSum1);
                        vo.setBalanceDirection("贷");
                    }else {
                        vo.setBalance(balanceSum1);
                        vo.setCurrencyBalance(currencyBalanceSum1);
                    }
                    break;
                case "贷":
                    Double balanceSum2  = DoubleValueUtil.getNotNullVal(init.getBalance()) - he;
                    Double currencyBalanceSum2 = DoubleValueUtil.getNotNullVal(init.getCurrencyBalance()) - currencySum;
                    if (balanceSum2 < 0 && currencyBalanceSum2 <= 0){
                        vo.setBalance(-balanceSum2);
                        vo.setCurrencyBalance(-currencyBalanceSum2);
                        vo.setBalanceDirection("借");
                    }else {
                        vo.setBalance(balanceSum2);
                        vo.setCurrencyBalance(currencyBalanceSum2);
                    }
                    break;
            }
            if (vo.getSummary().equals("本期合计")) {
                balance = vo.getBalance();
                currencyBalance = vo.getCurrencyBalance();
            } else {
                vo.setBalance(DoubleValueUtil.getNotNullVal(balance, init.getBalance()));
                vo.setCurrencyBalance(DoubleValueUtil.getNotNullVal(currencyBalance, init.getCurrencyBalance()));
            }
            vo.setNumBalance(vo.getNum());
            vo.setVoucherDate(DateUtil.getMonthEnd(new SimpleDateFormat("yyyy-MM-dd").parse(eTime)));
        }
        initialBalance.addAll(statistical);
        return initialBalance;
    }


}





